diff options
99 files changed, 1958 insertions, 1915 deletions
diff --git a/Documentation/ko_KR/HOWTO b/Documentation/ko_KR/HOWTO index 2f48f205fedc..680e64635958 100644 --- a/Documentation/ko_KR/HOWTO +++ b/Documentation/ko_KR/HOWTO | |||
@@ -182,8 +182,8 @@ Documentation/DocBook/ 디렉토리 내에서 만들어지며 PDF, Postscript, H | |||
182 | 프로젝트를 봐야 한다. | 182 | 프로젝트를 봐야 한다. |
183 | http://kernelnewbies.org | 183 | http://kernelnewbies.org |
184 | 그곳은 거의 모든 종류의 기본적인 커널 개발 질문들(질문하기 전에 먼저 | 184 | 그곳은 거의 모든 종류의 기본적인 커널 개발 질문들(질문하기 전에 먼저 |
185 | 아카이브를 찾아봐라. 과거에 이미 답변되었을 수도 있다)을 할수있는 도움이 | 185 | 아카이브를 찾아봐라. 과거에 이미 답변되었을 수도 있다)을 할 수 있는 도움이 |
186 | 될만한 메일링 리스트가 있다. 또한 실시간으로 질문 할수 있는 IRC 채널도 | 186 | 될만한 메일링 리스트가 있다. 또한 실시간으로 질문 할 수 있는 IRC 채널도 |
187 | 가지고 있으며 리눅스 커널 개발을 배우는 데 유용한 문서들을 보유하고 있다. | 187 | 가지고 있으며 리눅스 커널 개발을 배우는 데 유용한 문서들을 보유하고 있다. |
188 | 188 | ||
189 | 웹사이트는 코드구성, 서브시스템들, 그리고 현재 프로젝트들 | 189 | 웹사이트는 코드구성, 서브시스템들, 그리고 현재 프로젝트들 |
@@ -245,7 +245,7 @@ Documentation/DocBook/ 디렉토리 내에서 만들어지며 PDF, Postscript, H | |||
245 | 것을 기억해라. 왜냐하면 변경이 자체내에서만 발생하고 추가된 코드가 | 245 | 것을 기억해라. 왜냐하면 변경이 자체내에서만 발생하고 추가된 코드가 |
246 | 드라이버 외부의 다른 부분에는 영향을 주지 않으므로 그런 변경은 | 246 | 드라이버 외부의 다른 부분에는 영향을 주지 않으므로 그런 변경은 |
247 | 회귀(역자주: 이전에는 존재하지 않았지만 새로운 기능추가나 변경으로 인해 | 247 | 회귀(역자주: 이전에는 존재하지 않았지만 새로운 기능추가나 변경으로 인해 |
248 | 생겨난 버그)를 일으킬 만한 위험을 가지고 있지 않기 때문이다. -rc1이 | 248 | 생겨난 버그)를 일으킬 만한 위험을 가지고 있지 않기 때문이다. -rc1이 |
249 | 배포된 이후에 git를 사용하여 패치들을 Linus에게 보낼수 있지만 패치들은 | 249 | 배포된 이후에 git를 사용하여 패치들을 Linus에게 보낼수 있지만 패치들은 |
250 | 공식적인 메일링 리스트로 보내서 검토를 받을 필요가 있다. | 250 | 공식적인 메일링 리스트로 보내서 검토를 받을 필요가 있다. |
251 | - 새로운 -rc는 Linus가 현재 git tree가 테스트 하기에 충분히 안정된 상태에 | 251 | - 새로운 -rc는 Linus가 현재 git tree가 테스트 하기에 충분히 안정된 상태에 |
@@ -455,7 +455,7 @@ bugme-janitor 메일링 리스트(bugzilla에 모든 변화들이 여기서 메 | |||
455 | - 의견 | 455 | - 의견 |
456 | - 변경을 위한 요구 | 456 | - 변경을 위한 요구 |
457 | - 당위성을 위한 요구 | 457 | - 당위성을 위한 요구 |
458 | - 고 | 458 | - 묵 |
459 | 459 | ||
460 | 기억하라. 이것들은 여러분의 패치가 커널로 들어가기 위한 과정이다. 여러분의 | 460 | 기억하라. 이것들은 여러분의 패치가 커널로 들어가기 위한 과정이다. 여러분의 |
461 | 패치들은 비판과 다른 의견을 받을 수 있고 그것들을 기술적인 레벨로 평가하고 | 461 | 패치들은 비판과 다른 의견을 받을 수 있고 그것들을 기술적인 레벨로 평가하고 |
@@ -472,7 +472,7 @@ bugme-janitor 메일링 리스트(bugzilla에 모든 변화들이 여기서 메 | |||
472 | 가능한한 가장 좋은 기술적인 해답을 찾고 있는 커뮤니티에서는 항상 | 472 | 가능한한 가장 좋은 기술적인 해답을 찾고 있는 커뮤니티에서는 항상 |
473 | 어떤 패치가 얼마나 좋은지에 관하여 다른 의견들이 있을 수 있다. 여러분은 | 473 | 어떤 패치가 얼마나 좋은지에 관하여 다른 의견들이 있을 수 있다. 여러분은 |
474 | 협조적이어야 하고 기꺼이 여러분의 생각을 커널 내에 맞추어야 한다. 아니면 | 474 | 협조적이어야 하고 기꺼이 여러분의 생각을 커널 내에 맞추어야 한다. 아니면 |
475 | 적어도 여러분의 것이 가치있다는 것을 명하여야 한다. 잘못된 것도 여러분이 | 475 | 적어도 여러분의 것이 가치있다는 것을 명하여야 한다. 잘못된 것도 여러분이 |
476 | 올바른 방향의 해결책으로 이끌어갈 의지가 있다면 받아들여질 것이라는 점을 | 476 | 올바른 방향의 해결책으로 이끌어갈 의지가 있다면 받아들여질 것이라는 점을 |
477 | 기억하라. | 477 | 기억하라. |
478 | 478 | ||
@@ -488,21 +488,21 @@ bugme-janitor 메일링 리스트(bugzilla에 모든 변화들이 여기서 메 | |||
488 | 커널 커뮤니티는 가장 전통적인 회사의 개발 환경과는 다르다. 여기에 여러분들의 | 488 | 커널 커뮤니티는 가장 전통적인 회사의 개발 환경과는 다르다. 여기에 여러분들의 |
489 | 문제를 피하기 위한 목록이 있다. | 489 | 문제를 피하기 위한 목록이 있다. |
490 | 여러분들이 제안한 변경들에 관하여 말할 때 좋은 것들 : | 490 | 여러분들이 제안한 변경들에 관하여 말할 때 좋은 것들 : |
491 | - "이것은 여러 문제들을 해합니다." | 491 | - "이것은 여러 문제들을 해합니다." |
492 | - "이것은 2000 라인의 코드를 거합니다." | 492 | - "이것은 2000 라인의 코드를 입니다." |
493 | - "이것은 내가 말하려는 것에 관해 설명하는 패치입니다." | 493 | - "이것은 내가 말하려는 것에 관해 설명하는 패치입니다." |
494 | - "나는 5개의 다른 아키텍쳐에서 그것을 테스트했로..." | 494 | - "나는 5개의 다른 아키텍쳐에서 그것을 테스트 했으..." |
495 | - "여기에 일련의 작은 패치들이 있음로..." | 495 | - "여기에 일련의 작은 패치들이 있..." |
496 | - "이것은 일반적인 머신에서 성능을 향상시으로..." | 496 | - "이것은 일반적인 머신에서 성능을 향상으로..." |
497 | 497 | ||
498 | 여러분들이 말할 때 피해야 할 좋지 않은 것들 : | 498 | 여러분들이 말할 때 피해야 할 좋지 않은 것들 : |
499 | - "우리를 그것을 AIT/ptx/Solaris에서 이러한 방법으로 했다. 그러므로 그것은 좋은 것임에 틀립없다..." | 499 | - "우리는 그것을 AIX/ptx/Solaris에서 이러한 방법으로 했다. 그러므로 그것은 좋은 것임에 틀림없다..." |
500 | - "나는 20년동안 이것을 해왔다. 그러므로..." | 500 | - "나는 20년동안 이것을 해왔다. 그러므로..." |
501 | - "이것은 돈을 벌기위해 나의 회사가 필요로 하는 것이다." | 501 | - "이것은 돈을 벌기위해 나의 회사가 필요로 하는 것이다." |
502 | - "이것은 우리의 엔터프라이즈 상품 라인을 위한 것이다." | 502 | - "이것은 우리의 엔터프라이즈 상품 라인을 위한 것이다." |
503 | - "여기에 나의 생각을 말하고 있는 1000 페이지 설계 문서가 있다." | 503 | - "여기에 나의 생각을 말하고 있는 1000 페이지 설계 문서가 있다." |
504 | - "나는 6달동안 이것을 했으니..." | 504 | - "나는 6달동안 이것을 했으니..." |
505 | - "여기에 5000라인 짜리 패치가 있으니..." | 505 | - "여기에 5000 라인 짜리 패치가 있으니..." |
506 | - "나는 현재 뒤죽박죽인 것을 재작성했다. 그리고 여기에..." | 506 | - "나는 현재 뒤죽박죽인 것을 재작성했다. 그리고 여기에..." |
507 | - "나는 마감시한을 가지고 있으므로 이 패치는 지금 적용될 필요가 있다." | 507 | - "나는 마감시한을 가지고 있으므로 이 패치는 지금 적용될 필요가 있다." |
508 | 508 | ||
@@ -574,6 +574,7 @@ Pat이라는 이름을 가진 여자가 있을 수도 있는 것이다. 리눅 | |||
574 | 또한 완성되지 않았고 "나중에 수정될 것이다." 와 같은 것들을 포함하는 | 574 | 또한 완성되지 않았고 "나중에 수정될 것이다." 와 같은 것들을 포함하는 |
575 | 패치들은 받아들여지지 않을 것이라는 점을 유념하라. | 575 | 패치들은 받아들여지지 않을 것이라는 점을 유념하라. |
576 | 576 | ||
577 | |||
577 | 변경을 정당화해라 | 578 | 변경을 정당화해라 |
578 | ----------------- | 579 | ----------------- |
579 | 580 | ||
diff --git a/Documentation/ko_KR/stable_api_nonsense.txt b/Documentation/ko_KR/stable_api_nonsense.txt index 8f2b0e1d98c4..51f85ade4190 100644 --- a/Documentation/ko_KR/stable_api_nonsense.txt +++ b/Documentation/ko_KR/stable_api_nonsense.txt | |||
@@ -106,12 +106,12 @@ Greg Kroah-Hartman <greg@kroah.com> | |||
106 | --------------------------------- | 106 | --------------------------------- |
107 | 107 | ||
108 | 리눅스 커널 드라이버를 계속해서 메인 커널 트리에 반영하지 않고 | 108 | 리눅스 커널 드라이버를 계속해서 메인 커널 트리에 반영하지 않고 |
109 | 유지보수하려고 하는 사들과 이 문제를 논의하게 되면 훨씬 더 | 109 | 유지보수하려고 하는 사들과 이 문제를 논의하게 되면 훨씬 더 |
110 | "논란의 여지가 많은" 주제가 될 것이다. | 110 | "논란의 여지가 많은" 주제가 될 것이다. |
111 | 111 | ||
112 | 리눅스 커널 개발은 끊임없이 빠른 속도로 이루어지고 있으며 결코 | 112 | 리눅스 커널 개발은 끊임없이 빠른 속도로 이루어지고 있으며 결코 |
113 | 느슨해진 적이 없다. 커널 개발자들이 현재 인터페이스들에서 버그를 | 113 | 느슨해진 적이 없다. 커널 개발자들이 현재 인터페이스들에서 버그를 |
114 | 발견하거나 무엇인가 할수 있는 더 좋은 방법을 찾게 되었다고 하자. | 114 | 발견하거나 무엇인가 할 수 있는 더 좋은 방법을 찾게 되었다고 하자. |
115 | 그들이 발견한 것을 실행한다면 아마도 더 잘 동작하도록 현재 인터페이스들을 | 115 | 그들이 발견한 것을 실행한다면 아마도 더 잘 동작하도록 현재 인터페이스들을 |
116 | 수정하게 될 것이다. 그들이 그런 일을 하게되면 함수 이름들은 변하게 되고, | 116 | 수정하게 될 것이다. 그들이 그런 일을 하게되면 함수 이름들은 변하게 되고, |
117 | 구조체들은 늘어나거나 줄어들게 되고, 함수 파라미터들은 재작업될 것이다. | 117 | 구조체들은 늘어나거나 줄어들게 되고, 함수 파라미터들은 재작업될 것이다. |
@@ -174,7 +174,7 @@ GPL을 따르는 배포 드라이버에 관해 얘기하고 있다는 것을 상 | |||
174 | 동작하는 것을 보장한다. | 174 | 동작하는 것을 보장한다. |
175 | 175 | ||
176 | 메인 커널 트리에 여러분의 드라이버를 반영하면 얻게 되는 장점들은 다음과 같다. | 176 | 메인 커널 트리에 여러분의 드라이버를 반영하면 얻게 되는 장점들은 다음과 같다. |
177 | - 관리 드는 비용(원래 개발자의)은 줄어줄면서 드라이버의 질은 향상될 것이다. | 177 | - 관리 드는 비용(원래 개발자의)은 줄어줄면서 드라이버의 질은 향상될 것이다. |
178 | - 다른 개발자들이 여러분의 드라이버에 기능들을 추가 할 것이다. | 178 | - 다른 개발자들이 여러분의 드라이버에 기능들을 추가 할 것이다. |
179 | - 다른 사람들은 여러분의 드라이버에 버그를 발견하고 수정할 것이다. | 179 | - 다른 사람들은 여러분의 드라이버에 버그를 발견하고 수정할 것이다. |
180 | - 다른 사람들은 여러분의 드라이버의 개선점을 찾을 줄 것이다. | 180 | - 다른 사람들은 여러분의 드라이버의 개선점을 찾을 줄 것이다. |
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 43594d5116ef..cd5c1c97b043 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig | |||
@@ -2064,8 +2064,7 @@ config KEXEC | |||
2064 | 2064 | ||
2065 | It is an ongoing process to be certain the hardware in a machine | 2065 | It is an ongoing process to be certain the hardware in a machine |
2066 | is properly shutdown, so do not be surprised if this code does not | 2066 | is properly shutdown, so do not be surprised if this code does not |
2067 | initially work for you. It may help to enable device hotplugging | 2067 | initially work for you. |
2068 | support. | ||
2069 | 2068 | ||
2070 | config ATAGS_PROC | 2069 | config ATAGS_PROC |
2071 | bool "Export atags in procfs" | 2070 | bool "Export atags in procfs" |
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig index 5a768ad8e893..b36370d3eab9 100644 --- a/arch/ia64/Kconfig +++ b/arch/ia64/Kconfig | |||
@@ -565,9 +565,9 @@ config KEXEC | |||
565 | 565 | ||
566 | It is an ongoing process to be certain the hardware in a machine | 566 | It is an ongoing process to be certain the hardware in a machine |
567 | is properly shutdown, so do not be surprised if this code does not | 567 | is properly shutdown, so do not be surprised if this code does not |
568 | initially work for you. It may help to enable device hotplugging | 568 | initially work for you. As of this writing the exact hardware |
569 | support. As of this writing the exact hardware interface is | 569 | interface is strongly in flux, so no good recommendation can be |
570 | strongly in flux, so no good recommendation can be made. | 570 | made. |
571 | 571 | ||
572 | config CRASH_DUMP | 572 | config CRASH_DUMP |
573 | bool "kernel crash dumps" | 573 | bool "kernel crash dumps" |
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig index e12764c2a9d0..dccd7cec442d 100644 --- a/arch/mips/Kconfig +++ b/arch/mips/Kconfig | |||
@@ -2305,9 +2305,9 @@ config KEXEC | |||
2305 | 2305 | ||
2306 | It is an ongoing process to be certain the hardware in a machine | 2306 | It is an ongoing process to be certain the hardware in a machine |
2307 | is properly shutdown, so do not be surprised if this code does not | 2307 | is properly shutdown, so do not be surprised if this code does not |
2308 | initially work for you. It may help to enable device hotplugging | 2308 | initially work for you. As of this writing the exact hardware |
2309 | support. As of this writing the exact hardware interface is | 2309 | interface is strongly in flux, so no good recommendation can be |
2310 | strongly in flux, so no good recommendation can be made. | 2310 | made. |
2311 | 2311 | ||
2312 | config CRASH_DUMP | 2312 | config CRASH_DUMP |
2313 | bool "Kernel crash dumps" | 2313 | bool "Kernel crash dumps" |
diff --git a/arch/mips/kernel/vpe.c b/arch/mips/kernel/vpe.c index 1765bab000a0..faf84c5f2629 100644 --- a/arch/mips/kernel/vpe.c +++ b/arch/mips/kernel/vpe.c | |||
@@ -1335,8 +1335,9 @@ static ssize_t store_kill(struct device *dev, struct device_attribute *attr, | |||
1335 | 1335 | ||
1336 | return len; | 1336 | return len; |
1337 | } | 1337 | } |
1338 | static DEVICE_ATTR(kill, S_IWUSR, NULL, store_kill); | ||
1338 | 1339 | ||
1339 | static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr, | 1340 | static ssize_t ntcs_show(struct device *cd, struct device_attribute *attr, |
1340 | char *buf) | 1341 | char *buf) |
1341 | { | 1342 | { |
1342 | struct vpe *vpe = get_vpe(tclimit); | 1343 | struct vpe *vpe = get_vpe(tclimit); |
@@ -1344,7 +1345,7 @@ static ssize_t show_ntcs(struct device *cd, struct device_attribute *attr, | |||
1344 | return sprintf(buf, "%d\n", vpe->ntcs); | 1345 | return sprintf(buf, "%d\n", vpe->ntcs); |
1345 | } | 1346 | } |
1346 | 1347 | ||
1347 | static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, | 1348 | static ssize_t ntcs_store(struct device *dev, struct device_attribute *attr, |
1348 | const char *buf, size_t len) | 1349 | const char *buf, size_t len) |
1349 | { | 1350 | { |
1350 | struct vpe *vpe = get_vpe(tclimit); | 1351 | struct vpe *vpe = get_vpe(tclimit); |
@@ -1365,12 +1366,14 @@ static ssize_t store_ntcs(struct device *dev, struct device_attribute *attr, | |||
1365 | out_einval: | 1366 | out_einval: |
1366 | return -EINVAL; | 1367 | return -EINVAL; |
1367 | } | 1368 | } |
1369 | static DEVICE_ATTR_RW(ntcs); | ||
1368 | 1370 | ||
1369 | static struct device_attribute vpe_class_attributes[] = { | 1371 | static struct attribute vpe_attrs[] = { |
1370 | __ATTR(kill, S_IWUSR, NULL, store_kill), | 1372 | &dev_attr_kill.attr, |
1371 | __ATTR(ntcs, S_IRUGO | S_IWUSR, show_ntcs, store_ntcs), | 1373 | &dev_attr_ntcs.attr, |
1372 | {} | 1374 | NULL, |
1373 | }; | 1375 | }; |
1376 | ATTRIBUTE_GROUPS(vpe); | ||
1374 | 1377 | ||
1375 | static void vpe_device_release(struct device *cd) | 1378 | static void vpe_device_release(struct device *cd) |
1376 | { | 1379 | { |
@@ -1381,7 +1384,7 @@ struct class vpe_class = { | |||
1381 | .name = "vpe", | 1384 | .name = "vpe", |
1382 | .owner = THIS_MODULE, | 1385 | .owner = THIS_MODULE, |
1383 | .dev_release = vpe_device_release, | 1386 | .dev_release = vpe_device_release, |
1384 | .dev_attrs = vpe_class_attributes, | 1387 | .dev_groups = vpe_groups, |
1385 | }; | 1388 | }; |
1386 | 1389 | ||
1387 | struct device vpe_device; | 1390 | struct device vpe_device; |
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 9cf59816d3e9..5aecda05e0da 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig | |||
@@ -369,9 +369,9 @@ config KEXEC | |||
369 | 369 | ||
370 | It is an ongoing process to be certain the hardware in a machine | 370 | It is an ongoing process to be certain the hardware in a machine |
371 | is properly shutdown, so do not be surprised if this code does not | 371 | is properly shutdown, so do not be surprised if this code does not |
372 | initially work for you. It may help to enable device hotplugging | 372 | initially work for you. As of this writing the exact hardware |
373 | support. As of this writing the exact hardware interface is | 373 | interface is strongly in flux, so no good recommendation can be |
374 | strongly in flux, so no good recommendation can be made. | 374 | made. |
375 | 375 | ||
376 | config CRASH_DUMP | 376 | config CRASH_DUMP |
377 | bool "Build a kdump crash kernel" | 377 | bool "Build a kdump crash kernel" |
diff --git a/arch/sh/Kconfig b/arch/sh/Kconfig index 1020dd85431a..1018ed3a3ca5 100644 --- a/arch/sh/Kconfig +++ b/arch/sh/Kconfig | |||
@@ -643,9 +643,9 @@ config KEXEC | |||
643 | 643 | ||
644 | It is an ongoing process to be certain the hardware in a machine | 644 | It is an ongoing process to be certain the hardware in a machine |
645 | is properly shutdown, so do not be surprised if this code does not | 645 | is properly shutdown, so do not be surprised if this code does not |
646 | initially work for you. It may help to enable device hotplugging | 646 | initially work for you. As of this writing the exact hardware |
647 | support. As of this writing the exact hardware interface is | 647 | interface is strongly in flux, so no good recommendation can be |
648 | strongly in flux, so no good recommendation can be made. | 648 | made. |
649 | 649 | ||
650 | config CRASH_DUMP | 650 | config CRASH_DUMP |
651 | bool "kernel crash dumps (EXPERIMENTAL)" | 651 | bool "kernel crash dumps (EXPERIMENTAL)" |
diff --git a/arch/tile/include/asm/topology.h b/arch/tile/include/asm/topology.h index d5e86c9f74fd..d15c0d8d550f 100644 --- a/arch/tile/include/asm/topology.h +++ b/arch/tile/include/asm/topology.h | |||
@@ -89,9 +89,6 @@ static inline const struct cpumask *cpumask_of_node(int node) | |||
89 | #define topology_core_id(cpu) (cpu) | 89 | #define topology_core_id(cpu) (cpu) |
90 | #define topology_core_cpumask(cpu) ((void)(cpu), cpu_online_mask) | 90 | #define topology_core_cpumask(cpu) ((void)(cpu), cpu_online_mask) |
91 | #define topology_thread_cpumask(cpu) cpumask_of(cpu) | 91 | #define topology_thread_cpumask(cpu) cpumask_of(cpu) |
92 | |||
93 | /* indicates that pointers to the topology struct cpumask maps are valid */ | ||
94 | #define arch_provides_topology_pointers yes | ||
95 | #endif | 92 | #endif |
96 | 93 | ||
97 | #endif /* _ASM_TILE_TOPOLOGY_H */ | 94 | #endif /* _ASM_TILE_TOPOLOGY_H */ |
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 67e00740531c..27457379bbd5 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -1628,9 +1628,9 @@ config KEXEC | |||
1628 | 1628 | ||
1629 | It is an ongoing process to be certain the hardware in a machine | 1629 | It is an ongoing process to be certain the hardware in a machine |
1630 | is properly shutdown, so do not be surprised if this code does not | 1630 | is properly shutdown, so do not be surprised if this code does not |
1631 | initially work for you. It may help to enable device hotplugging | 1631 | initially work for you. As of this writing the exact hardware |
1632 | support. As of this writing the exact hardware interface is | 1632 | interface is strongly in flux, so no good recommendation can be |
1633 | strongly in flux, so no good recommendation can be made. | 1633 | made. |
1634 | 1634 | ||
1635 | config CRASH_DUMP | 1635 | config CRASH_DUMP |
1636 | bool "kernel crash dumps" | 1636 | bool "kernel crash dumps" |
diff --git a/arch/x86/include/asm/topology.h b/arch/x86/include/asm/topology.h index 095b21507b6a..d35f24e231cd 100644 --- a/arch/x86/include/asm/topology.h +++ b/arch/x86/include/asm/topology.h | |||
@@ -124,9 +124,6 @@ extern const struct cpumask *cpu_coregroup_mask(int cpu); | |||
124 | #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) | 124 | #define topology_core_id(cpu) (cpu_data(cpu).cpu_core_id) |
125 | #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) | 125 | #define topology_core_cpumask(cpu) (per_cpu(cpu_core_map, cpu)) |
126 | #define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) | 126 | #define topology_thread_cpumask(cpu) (per_cpu(cpu_sibling_map, cpu)) |
127 | |||
128 | /* indicates that pointers to the topology cpumask_t maps are valid */ | ||
129 | #define arch_provides_topology_pointers yes | ||
130 | #endif | 127 | #endif |
131 | 128 | ||
132 | static inline void arch_fix_phys_package_id(int num, u32 slot) | 129 | static inline void arch_fix_phys_package_id(int num, u32 slot) |
diff --git a/drivers/acpi/bgrt.c b/drivers/acpi/bgrt.c index be6039958545..a83e3c62c5a9 100644 --- a/drivers/acpi/bgrt.c +++ b/drivers/acpi/bgrt.c | |||
@@ -51,20 +51,14 @@ static ssize_t show_yoffset(struct device *dev, | |||
51 | } | 51 | } |
52 | static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL); | 52 | static DEVICE_ATTR(yoffset, S_IRUGO, show_yoffset, NULL); |
53 | 53 | ||
54 | static ssize_t show_image(struct file *file, struct kobject *kobj, | 54 | static ssize_t image_read(struct file *file, struct kobject *kobj, |
55 | struct bin_attribute *attr, char *buf, loff_t off, size_t count) | 55 | struct bin_attribute *attr, char *buf, loff_t off, size_t count) |
56 | { | 56 | { |
57 | memcpy(buf, attr->private + off, count); | 57 | memcpy(buf, attr->private + off, count); |
58 | return count; | 58 | return count; |
59 | } | 59 | } |
60 | 60 | ||
61 | static struct bin_attribute image_attr = { | 61 | static BIN_ATTR_RO(image, 0); /* size gets filled in later */ |
62 | .attr = { | ||
63 | .name = "image", | ||
64 | .mode = S_IRUGO, | ||
65 | }, | ||
66 | .read = show_image, | ||
67 | }; | ||
68 | 62 | ||
69 | static struct attribute *bgrt_attributes[] = { | 63 | static struct attribute *bgrt_attributes[] = { |
70 | &dev_attr_version.attr, | 64 | &dev_attr_version.attr, |
@@ -75,8 +69,14 @@ static struct attribute *bgrt_attributes[] = { | |||
75 | NULL, | 69 | NULL, |
76 | }; | 70 | }; |
77 | 71 | ||
72 | static struct bin_attribute *bgrt_bin_attributes[] = { | ||
73 | &bin_attr_image, | ||
74 | NULL, | ||
75 | }; | ||
76 | |||
78 | static struct attribute_group bgrt_attribute_group = { | 77 | static struct attribute_group bgrt_attribute_group = { |
79 | .attrs = bgrt_attributes, | 78 | .attrs = bgrt_attributes, |
79 | .bin_attrs = bgrt_bin_attributes, | ||
80 | }; | 80 | }; |
81 | 81 | ||
82 | static int __init bgrt_init(void) | 82 | static int __init bgrt_init(void) |
@@ -86,9 +86,8 @@ static int __init bgrt_init(void) | |||
86 | if (!bgrt_image) | 86 | if (!bgrt_image) |
87 | return -ENODEV; | 87 | return -ENODEV; |
88 | 88 | ||
89 | sysfs_bin_attr_init(&image_attr); | 89 | bin_attr_image.private = bgrt_image; |
90 | image_attr.private = bgrt_image; | 90 | bin_attr_image.size = bgrt_image_size; |
91 | image_attr.size = bgrt_image_size; | ||
92 | 91 | ||
93 | bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj); | 92 | bgrt_kobj = kobject_create_and_add("bgrt", acpi_kobj); |
94 | if (!bgrt_kobj) | 93 | if (!bgrt_kobj) |
@@ -98,14 +97,8 @@ static int __init bgrt_init(void) | |||
98 | if (ret) | 97 | if (ret) |
99 | goto out_kobject; | 98 | goto out_kobject; |
100 | 99 | ||
101 | ret = sysfs_create_bin_file(bgrt_kobj, &image_attr); | ||
102 | if (ret) | ||
103 | goto out_group; | ||
104 | |||
105 | return 0; | 100 | return 0; |
106 | 101 | ||
107 | out_group: | ||
108 | sysfs_remove_group(bgrt_kobj, &bgrt_attribute_group); | ||
109 | out_kobject: | 102 | out_kobject: |
110 | kobject_put(bgrt_kobj); | 103 | kobject_put(bgrt_kobj); |
111 | return ret; | 104 | return ret; |
diff --git a/drivers/base/base.h b/drivers/base/base.h index b8bdfe61daa6..2cbc6774f4cd 100644 --- a/drivers/base/base.h +++ b/drivers/base/base.h | |||
@@ -119,6 +119,16 @@ static inline int driver_match_device(struct device_driver *drv, | |||
119 | return drv->bus->match ? drv->bus->match(dev, drv) : 1; | 119 | return drv->bus->match ? drv->bus->match(dev, drv) : 1; |
120 | } | 120 | } |
121 | 121 | ||
122 | extern int driver_add_groups(struct device_driver *drv, | ||
123 | const struct attribute_group **groups); | ||
124 | extern void driver_remove_groups(struct device_driver *drv, | ||
125 | const struct attribute_group **groups); | ||
126 | |||
127 | extern int device_add_groups(struct device *dev, | ||
128 | const struct attribute_group **groups); | ||
129 | extern void device_remove_groups(struct device *dev, | ||
130 | const struct attribute_group **groups); | ||
131 | |||
122 | extern char *make_class_name(const char *name, struct kobject *kobj); | 132 | extern char *make_class_name(const char *name, struct kobject *kobj); |
123 | 133 | ||
124 | extern int devres_release_all(struct device *dev); | 134 | extern int devres_release_all(struct device *dev); |
diff --git a/drivers/base/bus.c b/drivers/base/bus.c index d414331b480e..4c289ab91357 100644 --- a/drivers/base/bus.c +++ b/drivers/base/bus.c | |||
@@ -17,6 +17,7 @@ | |||
17 | #include <linux/init.h> | 17 | #include <linux/init.h> |
18 | #include <linux/string.h> | 18 | #include <linux/string.h> |
19 | #include <linux/mutex.h> | 19 | #include <linux/mutex.h> |
20 | #include <linux/sysfs.h> | ||
20 | #include "base.h" | 21 | #include "base.h" |
21 | #include "power/power.h" | 22 | #include "power/power.h" |
22 | 23 | ||
@@ -165,8 +166,8 @@ static const struct kset_uevent_ops bus_uevent_ops = { | |||
165 | static struct kset *bus_kset; | 166 | static struct kset *bus_kset; |
166 | 167 | ||
167 | /* Manually detach a device from its associated driver. */ | 168 | /* Manually detach a device from its associated driver. */ |
168 | static ssize_t driver_unbind(struct device_driver *drv, | 169 | static ssize_t unbind_store(struct device_driver *drv, const char *buf, |
169 | const char *buf, size_t count) | 170 | size_t count) |
170 | { | 171 | { |
171 | struct bus_type *bus = bus_get(drv->bus); | 172 | struct bus_type *bus = bus_get(drv->bus); |
172 | struct device *dev; | 173 | struct device *dev; |
@@ -185,15 +186,15 @@ static ssize_t driver_unbind(struct device_driver *drv, | |||
185 | bus_put(bus); | 186 | bus_put(bus); |
186 | return err; | 187 | return err; |
187 | } | 188 | } |
188 | static DRIVER_ATTR(unbind, S_IWUSR, NULL, driver_unbind); | 189 | static DRIVER_ATTR_WO(unbind); |
189 | 190 | ||
190 | /* | 191 | /* |
191 | * Manually attach a device to a driver. | 192 | * Manually attach a device to a driver. |
192 | * Note: the driver must want to bind to the device, | 193 | * Note: the driver must want to bind to the device, |
193 | * it is not possible to override the driver's id table. | 194 | * it is not possible to override the driver's id table. |
194 | */ | 195 | */ |
195 | static ssize_t driver_bind(struct device_driver *drv, | 196 | static ssize_t bind_store(struct device_driver *drv, const char *buf, |
196 | const char *buf, size_t count) | 197 | size_t count) |
197 | { | 198 | { |
198 | struct bus_type *bus = bus_get(drv->bus); | 199 | struct bus_type *bus = bus_get(drv->bus); |
199 | struct device *dev; | 200 | struct device *dev; |
@@ -221,7 +222,7 @@ static ssize_t driver_bind(struct device_driver *drv, | |||
221 | bus_put(bus); | 222 | bus_put(bus); |
222 | return err; | 223 | return err; |
223 | } | 224 | } |
224 | static DRIVER_ATTR(bind, S_IWUSR, NULL, driver_bind); | 225 | static DRIVER_ATTR_WO(bind); |
225 | 226 | ||
226 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) | 227 | static ssize_t show_drivers_autoprobe(struct bus_type *bus, char *buf) |
227 | { | 228 | { |
@@ -460,7 +461,7 @@ static int device_add_attrs(struct bus_type *bus, struct device *dev) | |||
460 | if (!bus->dev_attrs) | 461 | if (!bus->dev_attrs) |
461 | return 0; | 462 | return 0; |
462 | 463 | ||
463 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) { | 464 | for (i = 0; bus->dev_attrs[i].attr.name; i++) { |
464 | error = device_create_file(dev, &bus->dev_attrs[i]); | 465 | error = device_create_file(dev, &bus->dev_attrs[i]); |
465 | if (error) { | 466 | if (error) { |
466 | while (--i >= 0) | 467 | while (--i >= 0) |
@@ -476,7 +477,7 @@ static void device_remove_attrs(struct bus_type *bus, struct device *dev) | |||
476 | int i; | 477 | int i; |
477 | 478 | ||
478 | if (bus->dev_attrs) { | 479 | if (bus->dev_attrs) { |
479 | for (i = 0; attr_name(bus->dev_attrs[i]); i++) | 480 | for (i = 0; bus->dev_attrs[i].attr.name; i++) |
480 | device_remove_file(dev, &bus->dev_attrs[i]); | 481 | device_remove_file(dev, &bus->dev_attrs[i]); |
481 | } | 482 | } |
482 | } | 483 | } |
@@ -499,6 +500,9 @@ int bus_add_device(struct device *dev) | |||
499 | error = device_add_attrs(bus, dev); | 500 | error = device_add_attrs(bus, dev); |
500 | if (error) | 501 | if (error) |
501 | goto out_put; | 502 | goto out_put; |
503 | error = device_add_groups(dev, bus->dev_groups); | ||
504 | if (error) | ||
505 | goto out_groups; | ||
502 | error = sysfs_create_link(&bus->p->devices_kset->kobj, | 506 | error = sysfs_create_link(&bus->p->devices_kset->kobj, |
503 | &dev->kobj, dev_name(dev)); | 507 | &dev->kobj, dev_name(dev)); |
504 | if (error) | 508 | if (error) |
@@ -513,6 +517,8 @@ int bus_add_device(struct device *dev) | |||
513 | 517 | ||
514 | out_subsys: | 518 | out_subsys: |
515 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); | 519 | sysfs_remove_link(&bus->p->devices_kset->kobj, dev_name(dev)); |
520 | out_groups: | ||
521 | device_remove_groups(dev, bus->dev_groups); | ||
516 | out_id: | 522 | out_id: |
517 | device_remove_attrs(bus, dev); | 523 | device_remove_attrs(bus, dev); |
518 | out_put: | 524 | out_put: |
@@ -575,6 +581,7 @@ void bus_remove_device(struct device *dev) | |||
575 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, | 581 | sysfs_remove_link(&dev->bus->p->devices_kset->kobj, |
576 | dev_name(dev)); | 582 | dev_name(dev)); |
577 | device_remove_attrs(dev->bus, dev); | 583 | device_remove_attrs(dev->bus, dev); |
584 | device_remove_groups(dev, dev->bus->dev_groups); | ||
578 | if (klist_node_attached(&dev->p->knode_bus)) | 585 | if (klist_node_attached(&dev->p->knode_bus)) |
579 | klist_del(&dev->p->knode_bus); | 586 | klist_del(&dev->p->knode_bus); |
580 | 587 | ||
@@ -590,7 +597,7 @@ static int driver_add_attrs(struct bus_type *bus, struct device_driver *drv) | |||
590 | int i; | 597 | int i; |
591 | 598 | ||
592 | if (bus->drv_attrs) { | 599 | if (bus->drv_attrs) { |
593 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) { | 600 | for (i = 0; bus->drv_attrs[i].attr.name; i++) { |
594 | error = driver_create_file(drv, &bus->drv_attrs[i]); | 601 | error = driver_create_file(drv, &bus->drv_attrs[i]); |
595 | if (error) | 602 | if (error) |
596 | goto err; | 603 | goto err; |
@@ -610,7 +617,7 @@ static void driver_remove_attrs(struct bus_type *bus, | |||
610 | int i; | 617 | int i; |
611 | 618 | ||
612 | if (bus->drv_attrs) { | 619 | if (bus->drv_attrs) { |
613 | for (i = 0; attr_name(bus->drv_attrs[i]); i++) | 620 | for (i = 0; bus->drv_attrs[i].attr.name; i++) |
614 | driver_remove_file(drv, &bus->drv_attrs[i]); | 621 | driver_remove_file(drv, &bus->drv_attrs[i]); |
615 | } | 622 | } |
616 | } | 623 | } |
@@ -659,8 +666,8 @@ static void remove_probe_files(struct bus_type *bus) | |||
659 | bus_remove_file(bus, &bus_attr_drivers_probe); | 666 | bus_remove_file(bus, &bus_attr_drivers_probe); |
660 | } | 667 | } |
661 | 668 | ||
662 | static ssize_t driver_uevent_store(struct device_driver *drv, | 669 | static ssize_t uevent_store(struct device_driver *drv, const char *buf, |
663 | const char *buf, size_t count) | 670 | size_t count) |
664 | { | 671 | { |
665 | enum kobject_action action; | 672 | enum kobject_action action; |
666 | 673 | ||
@@ -668,7 +675,7 @@ static ssize_t driver_uevent_store(struct device_driver *drv, | |||
668 | kobject_uevent(&drv->p->kobj, action); | 675 | kobject_uevent(&drv->p->kobj, action); |
669 | return count; | 676 | return count; |
670 | } | 677 | } |
671 | static DRIVER_ATTR(uevent, S_IWUSR, NULL, driver_uevent_store); | 678 | static DRIVER_ATTR_WO(uevent); |
672 | 679 | ||
673 | /** | 680 | /** |
674 | * bus_add_driver - Add a driver to the bus. | 681 | * bus_add_driver - Add a driver to the bus. |
@@ -719,6 +726,10 @@ int bus_add_driver(struct device_driver *drv) | |||
719 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", | 726 | printk(KERN_ERR "%s: driver_add_attrs(%s) failed\n", |
720 | __func__, drv->name); | 727 | __func__, drv->name); |
721 | } | 728 | } |
729 | error = driver_add_groups(drv, bus->drv_groups); | ||
730 | if (error) | ||
731 | printk(KERN_ERR "%s: driver_create_groups(%s) failed\n", | ||
732 | __func__, drv->name); | ||
722 | 733 | ||
723 | if (!drv->suppress_bind_attrs) { | 734 | if (!drv->suppress_bind_attrs) { |
724 | error = add_bind_files(drv); | 735 | error = add_bind_files(drv); |
@@ -756,6 +767,7 @@ void bus_remove_driver(struct device_driver *drv) | |||
756 | if (!drv->suppress_bind_attrs) | 767 | if (!drv->suppress_bind_attrs) |
757 | remove_bind_files(drv); | 768 | remove_bind_files(drv); |
758 | driver_remove_attrs(drv->bus, drv); | 769 | driver_remove_attrs(drv->bus, drv); |
770 | driver_remove_groups(drv, drv->bus->drv_groups); | ||
759 | driver_remove_file(drv, &driver_attr_uevent); | 771 | driver_remove_file(drv, &driver_attr_uevent); |
760 | klist_remove(&drv->p->knode_bus); | 772 | klist_remove(&drv->p->knode_bus); |
761 | pr_debug("bus: '%s': remove driver %s\n", drv->bus->name, drv->name); | 773 | 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) | |||
846 | int i; | 858 | int i; |
847 | 859 | ||
848 | if (bus->bus_attrs) { | 860 | if (bus->bus_attrs) { |
849 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) { | 861 | for (i = 0; bus->bus_attrs[i].attr.name; i++) { |
850 | error = bus_create_file(bus, &bus->bus_attrs[i]); | 862 | error = bus_create_file(bus, &bus->bus_attrs[i]); |
851 | if (error) | 863 | if (error) |
852 | goto err; | 864 | goto err; |
@@ -865,11 +877,23 @@ static void bus_remove_attrs(struct bus_type *bus) | |||
865 | int i; | 877 | int i; |
866 | 878 | ||
867 | if (bus->bus_attrs) { | 879 | if (bus->bus_attrs) { |
868 | for (i = 0; attr_name(bus->bus_attrs[i]); i++) | 880 | for (i = 0; bus->bus_attrs[i].attr.name; i++) |
869 | bus_remove_file(bus, &bus->bus_attrs[i]); | 881 | bus_remove_file(bus, &bus->bus_attrs[i]); |
870 | } | 882 | } |
871 | } | 883 | } |
872 | 884 | ||
885 | static int bus_add_groups(struct bus_type *bus, | ||
886 | const struct attribute_group **groups) | ||
887 | { | ||
888 | return sysfs_create_groups(&bus->p->subsys.kobj, groups); | ||
889 | } | ||
890 | |||
891 | static void bus_remove_groups(struct bus_type *bus, | ||
892 | const struct attribute_group **groups) | ||
893 | { | ||
894 | sysfs_remove_groups(&bus->p->subsys.kobj, groups); | ||
895 | } | ||
896 | |||
873 | static void klist_devices_get(struct klist_node *n) | 897 | static void klist_devices_get(struct klist_node *n) |
874 | { | 898 | { |
875 | struct device_private *dev_prv = to_device_private_bus(n); | 899 | struct device_private *dev_prv = to_device_private_bus(n); |
@@ -962,10 +986,15 @@ int bus_register(struct bus_type *bus) | |||
962 | retval = bus_add_attrs(bus); | 986 | retval = bus_add_attrs(bus); |
963 | if (retval) | 987 | if (retval) |
964 | goto bus_attrs_fail; | 988 | goto bus_attrs_fail; |
989 | retval = bus_add_groups(bus, bus->bus_groups); | ||
990 | if (retval) | ||
991 | goto bus_groups_fail; | ||
965 | 992 | ||
966 | pr_debug("bus: '%s': registered\n", bus->name); | 993 | pr_debug("bus: '%s': registered\n", bus->name); |
967 | return 0; | 994 | return 0; |
968 | 995 | ||
996 | bus_groups_fail: | ||
997 | bus_remove_attrs(bus); | ||
969 | bus_attrs_fail: | 998 | bus_attrs_fail: |
970 | remove_probe_files(bus); | 999 | remove_probe_files(bus); |
971 | bus_probe_files_fail: | 1000 | bus_probe_files_fail: |
@@ -996,6 +1025,7 @@ void bus_unregister(struct bus_type *bus) | |||
996 | if (bus->dev_root) | 1025 | if (bus->dev_root) |
997 | device_unregister(bus->dev_root); | 1026 | device_unregister(bus->dev_root); |
998 | bus_remove_attrs(bus); | 1027 | bus_remove_attrs(bus); |
1028 | bus_remove_groups(bus, bus->bus_groups); | ||
999 | remove_probe_files(bus); | 1029 | remove_probe_files(bus); |
1000 | kset_unregister(bus->p->drivers_kset); | 1030 | kset_unregister(bus->p->drivers_kset); |
1001 | kset_unregister(bus->p->devices_kset); | 1031 | kset_unregister(bus->p->devices_kset); |
diff --git a/drivers/base/class.c b/drivers/base/class.c index 3ce845471327..8b7818b80056 100644 --- a/drivers/base/class.c +++ b/drivers/base/class.c | |||
@@ -135,7 +135,7 @@ static int add_class_attrs(struct class *cls) | |||
135 | int error = 0; | 135 | int error = 0; |
136 | 136 | ||
137 | if (cls->class_attrs) { | 137 | if (cls->class_attrs) { |
138 | for (i = 0; attr_name(cls->class_attrs[i]); i++) { | 138 | for (i = 0; cls->class_attrs[i].attr.name; i++) { |
139 | error = class_create_file(cls, &cls->class_attrs[i]); | 139 | error = class_create_file(cls, &cls->class_attrs[i]); |
140 | if (error) | 140 | if (error) |
141 | goto error; | 141 | goto error; |
@@ -154,7 +154,7 @@ static void remove_class_attrs(struct class *cls) | |||
154 | int i; | 154 | int i; |
155 | 155 | ||
156 | if (cls->class_attrs) { | 156 | if (cls->class_attrs) { |
157 | for (i = 0; attr_name(cls->class_attrs[i]); i++) | 157 | for (i = 0; cls->class_attrs[i].attr.name; i++) |
158 | class_remove_file(cls, &cls->class_attrs[i]); | 158 | class_remove_file(cls, &cls->class_attrs[i]); |
159 | } | 159 | } |
160 | } | 160 | } |
diff --git a/drivers/base/core.c b/drivers/base/core.c index 8856d74545d9..c7b0925f627a 100644 --- a/drivers/base/core.c +++ b/drivers/base/core.c | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/async.h> | 26 | #include <linux/async.h> |
27 | #include <linux/pm_runtime.h> | 27 | #include <linux/pm_runtime.h> |
28 | #include <linux/netdevice.h> | 28 | #include <linux/netdevice.h> |
29 | #include <linux/sysfs.h> | ||
29 | 30 | ||
30 | #include "base.h" | 31 | #include "base.h" |
31 | #include "power/power.h" | 32 | #include "power/power.h" |
@@ -36,9 +37,9 @@ long sysfs_deprecated = 1; | |||
36 | #else | 37 | #else |
37 | long sysfs_deprecated = 0; | 38 | long sysfs_deprecated = 0; |
38 | #endif | 39 | #endif |
39 | static __init int sysfs_deprecated_setup(char *arg) | 40 | static int __init sysfs_deprecated_setup(char *arg) |
40 | { | 41 | { |
41 | return strict_strtol(arg, 10, &sysfs_deprecated); | 42 | return kstrtol(arg, 10, &sysfs_deprecated); |
42 | } | 43 | } |
43 | early_param("sysfs.deprecated", sysfs_deprecated_setup); | 44 | early_param("sysfs.deprecated", sysfs_deprecated_setup); |
44 | #endif | 45 | #endif |
@@ -345,7 +346,7 @@ static const struct kset_uevent_ops device_uevent_ops = { | |||
345 | .uevent = dev_uevent, | 346 | .uevent = dev_uevent, |
346 | }; | 347 | }; |
347 | 348 | ||
348 | static ssize_t show_uevent(struct device *dev, struct device_attribute *attr, | 349 | static ssize_t uevent_show(struct device *dev, struct device_attribute *attr, |
349 | char *buf) | 350 | char *buf) |
350 | { | 351 | { |
351 | struct kobject *top_kobj; | 352 | struct kobject *top_kobj; |
@@ -388,7 +389,7 @@ out: | |||
388 | return count; | 389 | return count; |
389 | } | 390 | } |
390 | 391 | ||
391 | static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | 392 | static ssize_t uevent_store(struct device *dev, struct device_attribute *attr, |
392 | const char *buf, size_t count) | 393 | const char *buf, size_t count) |
393 | { | 394 | { |
394 | enum kobject_action action; | 395 | enum kobject_action action; |
@@ -399,11 +400,9 @@ static ssize_t store_uevent(struct device *dev, struct device_attribute *attr, | |||
399 | dev_err(dev, "uevent: unknown action-string\n"); | 400 | dev_err(dev, "uevent: unknown action-string\n"); |
400 | return count; | 401 | return count; |
401 | } | 402 | } |
403 | static DEVICE_ATTR_RW(uevent); | ||
402 | 404 | ||
403 | static struct device_attribute uevent_attr = | 405 | static ssize_t online_show(struct device *dev, struct device_attribute *attr, |
404 | __ATTR(uevent, S_IRUGO | S_IWUSR, show_uevent, store_uevent); | ||
405 | |||
406 | static ssize_t show_online(struct device *dev, struct device_attribute *attr, | ||
407 | char *buf) | 406 | char *buf) |
408 | { | 407 | { |
409 | bool val; | 408 | bool val; |
@@ -414,7 +413,7 @@ static ssize_t show_online(struct device *dev, struct device_attribute *attr, | |||
414 | return sprintf(buf, "%u\n", val); | 413 | return sprintf(buf, "%u\n", val); |
415 | } | 414 | } |
416 | 415 | ||
417 | static ssize_t store_online(struct device *dev, struct device_attribute *attr, | 416 | static ssize_t online_store(struct device *dev, struct device_attribute *attr, |
418 | const char *buf, size_t count) | 417 | const char *buf, size_t count) |
419 | { | 418 | { |
420 | bool val; | 419 | bool val; |
@@ -429,9 +428,7 @@ static ssize_t store_online(struct device *dev, struct device_attribute *attr, | |||
429 | unlock_device_hotplug(); | 428 | unlock_device_hotplug(); |
430 | return ret < 0 ? ret : count; | 429 | return ret < 0 ? ret : count; |
431 | } | 430 | } |
432 | 431 | static DEVICE_ATTR_RW(online); | |
433 | static struct device_attribute online_attr = | ||
434 | __ATTR(online, S_IRUGO | S_IWUSR, show_online, store_online); | ||
435 | 432 | ||
436 | static int device_add_attributes(struct device *dev, | 433 | static int device_add_attributes(struct device *dev, |
437 | struct device_attribute *attrs) | 434 | struct device_attribute *attrs) |
@@ -440,7 +437,7 @@ static int device_add_attributes(struct device *dev, | |||
440 | int i; | 437 | int i; |
441 | 438 | ||
442 | if (attrs) { | 439 | if (attrs) { |
443 | for (i = 0; attr_name(attrs[i]); i++) { | 440 | for (i = 0; attrs[i].attr.name; i++) { |
444 | error = device_create_file(dev, &attrs[i]); | 441 | error = device_create_file(dev, &attrs[i]); |
445 | if (error) | 442 | if (error) |
446 | break; | 443 | break; |
@@ -458,7 +455,7 @@ static void device_remove_attributes(struct device *dev, | |||
458 | int i; | 455 | int i; |
459 | 456 | ||
460 | if (attrs) | 457 | if (attrs) |
461 | for (i = 0; attr_name(attrs[i]); i++) | 458 | for (i = 0; attrs[i].attr.name; i++) |
462 | device_remove_file(dev, &attrs[i]); | 459 | device_remove_file(dev, &attrs[i]); |
463 | } | 460 | } |
464 | 461 | ||
@@ -469,7 +466,7 @@ static int device_add_bin_attributes(struct device *dev, | |||
469 | int i; | 466 | int i; |
470 | 467 | ||
471 | if (attrs) { | 468 | if (attrs) { |
472 | for (i = 0; attr_name(attrs[i]); i++) { | 469 | for (i = 0; attrs[i].attr.name; i++) { |
473 | error = device_create_bin_file(dev, &attrs[i]); | 470 | error = device_create_bin_file(dev, &attrs[i]); |
474 | if (error) | 471 | if (error) |
475 | break; | 472 | break; |
@@ -487,38 +484,19 @@ static void device_remove_bin_attributes(struct device *dev, | |||
487 | int i; | 484 | int i; |
488 | 485 | ||
489 | if (attrs) | 486 | if (attrs) |
490 | for (i = 0; attr_name(attrs[i]); i++) | 487 | for (i = 0; attrs[i].attr.name; i++) |
491 | device_remove_bin_file(dev, &attrs[i]); | 488 | device_remove_bin_file(dev, &attrs[i]); |
492 | } | 489 | } |
493 | 490 | ||
494 | static int device_add_groups(struct device *dev, | 491 | int device_add_groups(struct device *dev, const struct attribute_group **groups) |
495 | const struct attribute_group **groups) | ||
496 | { | 492 | { |
497 | int error = 0; | 493 | return sysfs_create_groups(&dev->kobj, groups); |
498 | int i; | ||
499 | |||
500 | if (groups) { | ||
501 | for (i = 0; groups[i]; i++) { | ||
502 | error = sysfs_create_group(&dev->kobj, groups[i]); | ||
503 | if (error) { | ||
504 | while (--i >= 0) | ||
505 | sysfs_remove_group(&dev->kobj, | ||
506 | groups[i]); | ||
507 | break; | ||
508 | } | ||
509 | } | ||
510 | } | ||
511 | return error; | ||
512 | } | 494 | } |
513 | 495 | ||
514 | static void device_remove_groups(struct device *dev, | 496 | void device_remove_groups(struct device *dev, |
515 | const struct attribute_group **groups) | 497 | const struct attribute_group **groups) |
516 | { | 498 | { |
517 | int i; | 499 | sysfs_remove_groups(&dev->kobj, groups); |
518 | |||
519 | if (groups) | ||
520 | for (i = 0; groups[i]; i++) | ||
521 | sysfs_remove_group(&dev->kobj, groups[i]); | ||
522 | } | 500 | } |
523 | 501 | ||
524 | static int device_add_attrs(struct device *dev) | 502 | static int device_add_attrs(struct device *dev) |
@@ -550,7 +528,7 @@ static int device_add_attrs(struct device *dev) | |||
550 | goto err_remove_type_groups; | 528 | goto err_remove_type_groups; |
551 | 529 | ||
552 | if (device_supports_offline(dev) && !dev->offline_disabled) { | 530 | if (device_supports_offline(dev) && !dev->offline_disabled) { |
553 | error = device_create_file(dev, &online_attr); | 531 | error = device_create_file(dev, &dev_attr_online); |
554 | if (error) | 532 | if (error) |
555 | goto err_remove_type_groups; | 533 | goto err_remove_type_groups; |
556 | } | 534 | } |
@@ -578,7 +556,7 @@ static void device_remove_attrs(struct device *dev) | |||
578 | struct class *class = dev->class; | 556 | struct class *class = dev->class; |
579 | const struct device_type *type = dev->type; | 557 | const struct device_type *type = dev->type; |
580 | 558 | ||
581 | device_remove_file(dev, &online_attr); | 559 | device_remove_file(dev, &dev_attr_online); |
582 | device_remove_groups(dev, dev->groups); | 560 | device_remove_groups(dev, dev->groups); |
583 | 561 | ||
584 | if (type) | 562 | if (type) |
@@ -591,15 +569,12 @@ static void device_remove_attrs(struct device *dev) | |||
591 | } | 569 | } |
592 | } | 570 | } |
593 | 571 | ||
594 | 572 | static ssize_t dev_show(struct device *dev, struct device_attribute *attr, | |
595 | static ssize_t show_dev(struct device *dev, struct device_attribute *attr, | ||
596 | char *buf) | 573 | char *buf) |
597 | { | 574 | { |
598 | return print_dev_t(buf, dev->devt); | 575 | return print_dev_t(buf, dev->devt); |
599 | } | 576 | } |
600 | 577 | static DEVICE_ATTR_RO(dev); | |
601 | static struct device_attribute devt_attr = | ||
602 | __ATTR(dev, S_IRUGO, show_dev, NULL); | ||
603 | 578 | ||
604 | /* /sys/devices/ */ | 579 | /* /sys/devices/ */ |
605 | struct kset *devices_kset; | 580 | struct kset *devices_kset; |
@@ -626,6 +601,7 @@ int device_create_file(struct device *dev, | |||
626 | 601 | ||
627 | return error; | 602 | return error; |
628 | } | 603 | } |
604 | EXPORT_SYMBOL_GPL(device_create_file); | ||
629 | 605 | ||
630 | /** | 606 | /** |
631 | * device_remove_file - remove sysfs attribute file. | 607 | * device_remove_file - remove sysfs attribute file. |
@@ -638,6 +614,7 @@ void device_remove_file(struct device *dev, | |||
638 | if (dev) | 614 | if (dev) |
639 | sysfs_remove_file(&dev->kobj, &attr->attr); | 615 | sysfs_remove_file(&dev->kobj, &attr->attr); |
640 | } | 616 | } |
617 | EXPORT_SYMBOL_GPL(device_remove_file); | ||
641 | 618 | ||
642 | /** | 619 | /** |
643 | * device_create_bin_file - create sysfs binary attribute file for device. | 620 | * device_create_bin_file - create sysfs binary attribute file for device. |
@@ -748,6 +725,7 @@ void device_initialize(struct device *dev) | |||
748 | device_pm_init(dev); | 725 | device_pm_init(dev); |
749 | set_dev_node(dev, -1); | 726 | set_dev_node(dev, -1); |
750 | } | 727 | } |
728 | EXPORT_SYMBOL_GPL(device_initialize); | ||
751 | 729 | ||
752 | struct kobject *virtual_device_parent(struct device *dev) | 730 | struct kobject *virtual_device_parent(struct device *dev) |
753 | { | 731 | { |
@@ -1100,12 +1078,12 @@ int device_add(struct device *dev) | |||
1100 | if (platform_notify) | 1078 | if (platform_notify) |
1101 | platform_notify(dev); | 1079 | platform_notify(dev); |
1102 | 1080 | ||
1103 | error = device_create_file(dev, &uevent_attr); | 1081 | error = device_create_file(dev, &dev_attr_uevent); |
1104 | if (error) | 1082 | if (error) |
1105 | goto attrError; | 1083 | goto attrError; |
1106 | 1084 | ||
1107 | if (MAJOR(dev->devt)) { | 1085 | if (MAJOR(dev->devt)) { |
1108 | error = device_create_file(dev, &devt_attr); | 1086 | error = device_create_file(dev, &dev_attr_dev); |
1109 | if (error) | 1087 | if (error) |
1110 | goto ueventattrError; | 1088 | goto ueventattrError; |
1111 | 1089 | ||
@@ -1172,9 +1150,9 @@ done: | |||
1172 | device_remove_sys_dev_entry(dev); | 1150 | device_remove_sys_dev_entry(dev); |
1173 | devtattrError: | 1151 | devtattrError: |
1174 | if (MAJOR(dev->devt)) | 1152 | if (MAJOR(dev->devt)) |
1175 | device_remove_file(dev, &devt_attr); | 1153 | device_remove_file(dev, &dev_attr_dev); |
1176 | ueventattrError: | 1154 | ueventattrError: |
1177 | device_remove_file(dev, &uevent_attr); | 1155 | device_remove_file(dev, &dev_attr_uevent); |
1178 | attrError: | 1156 | attrError: |
1179 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); | 1157 | kobject_uevent(&dev->kobj, KOBJ_REMOVE); |
1180 | kobject_del(&dev->kobj); | 1158 | kobject_del(&dev->kobj); |
@@ -1187,6 +1165,7 @@ name_error: | |||
1187 | dev->p = NULL; | 1165 | dev->p = NULL; |
1188 | goto done; | 1166 | goto done; |
1189 | } | 1167 | } |
1168 | EXPORT_SYMBOL_GPL(device_add); | ||
1190 | 1169 | ||
1191 | /** | 1170 | /** |
1192 | * device_register - register a device with the system. | 1171 | * device_register - register a device with the system. |
@@ -1211,6 +1190,7 @@ int device_register(struct device *dev) | |||
1211 | device_initialize(dev); | 1190 | device_initialize(dev); |
1212 | return device_add(dev); | 1191 | return device_add(dev); |
1213 | } | 1192 | } |
1193 | EXPORT_SYMBOL_GPL(device_register); | ||
1214 | 1194 | ||
1215 | /** | 1195 | /** |
1216 | * get_device - increment reference count for device. | 1196 | * get_device - increment reference count for device. |
@@ -1224,6 +1204,7 @@ struct device *get_device(struct device *dev) | |||
1224 | { | 1204 | { |
1225 | return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; | 1205 | return dev ? kobj_to_dev(kobject_get(&dev->kobj)) : NULL; |
1226 | } | 1206 | } |
1207 | EXPORT_SYMBOL_GPL(get_device); | ||
1227 | 1208 | ||
1228 | /** | 1209 | /** |
1229 | * put_device - decrement reference count. | 1210 | * put_device - decrement reference count. |
@@ -1235,6 +1216,7 @@ void put_device(struct device *dev) | |||
1235 | if (dev) | 1216 | if (dev) |
1236 | kobject_put(&dev->kobj); | 1217 | kobject_put(&dev->kobj); |
1237 | } | 1218 | } |
1219 | EXPORT_SYMBOL_GPL(put_device); | ||
1238 | 1220 | ||
1239 | /** | 1221 | /** |
1240 | * device_del - delete device from system. | 1222 | * device_del - delete device from system. |
@@ -1266,7 +1248,7 @@ void device_del(struct device *dev) | |||
1266 | if (MAJOR(dev->devt)) { | 1248 | if (MAJOR(dev->devt)) { |
1267 | devtmpfs_delete_node(dev); | 1249 | devtmpfs_delete_node(dev); |
1268 | device_remove_sys_dev_entry(dev); | 1250 | device_remove_sys_dev_entry(dev); |
1269 | device_remove_file(dev, &devt_attr); | 1251 | device_remove_file(dev, &dev_attr_dev); |
1270 | } | 1252 | } |
1271 | if (dev->class) { | 1253 | if (dev->class) { |
1272 | device_remove_class_symlinks(dev); | 1254 | device_remove_class_symlinks(dev); |
@@ -1281,7 +1263,7 @@ void device_del(struct device *dev) | |||
1281 | klist_del(&dev->knode_class); | 1263 | klist_del(&dev->knode_class); |
1282 | mutex_unlock(&dev->class->p->mutex); | 1264 | mutex_unlock(&dev->class->p->mutex); |
1283 | } | 1265 | } |
1284 | device_remove_file(dev, &uevent_attr); | 1266 | device_remove_file(dev, &dev_attr_uevent); |
1285 | device_remove_attrs(dev); | 1267 | device_remove_attrs(dev); |
1286 | bus_remove_device(dev); | 1268 | bus_remove_device(dev); |
1287 | device_pm_remove(dev); | 1269 | device_pm_remove(dev); |
@@ -1297,6 +1279,7 @@ void device_del(struct device *dev) | |||
1297 | kobject_del(&dev->kobj); | 1279 | kobject_del(&dev->kobj); |
1298 | put_device(parent); | 1280 | put_device(parent); |
1299 | } | 1281 | } |
1282 | EXPORT_SYMBOL_GPL(device_del); | ||
1300 | 1283 | ||
1301 | /** | 1284 | /** |
1302 | * device_unregister - unregister device from system. | 1285 | * device_unregister - unregister device from system. |
@@ -1315,6 +1298,7 @@ void device_unregister(struct device *dev) | |||
1315 | device_del(dev); | 1298 | device_del(dev); |
1316 | put_device(dev); | 1299 | put_device(dev); |
1317 | } | 1300 | } |
1301 | EXPORT_SYMBOL_GPL(device_unregister); | ||
1318 | 1302 | ||
1319 | static struct device *next_device(struct klist_iter *i) | 1303 | static struct device *next_device(struct klist_iter *i) |
1320 | { | 1304 | { |
@@ -1403,6 +1387,7 @@ int device_for_each_child(struct device *parent, void *data, | |||
1403 | klist_iter_exit(&i); | 1387 | klist_iter_exit(&i); |
1404 | return error; | 1388 | return error; |
1405 | } | 1389 | } |
1390 | EXPORT_SYMBOL_GPL(device_for_each_child); | ||
1406 | 1391 | ||
1407 | /** | 1392 | /** |
1408 | * device_find_child - device iterator for locating a particular device. | 1393 | * device_find_child - device iterator for locating a particular device. |
@@ -1437,6 +1422,7 @@ struct device *device_find_child(struct device *parent, void *data, | |||
1437 | klist_iter_exit(&i); | 1422 | klist_iter_exit(&i); |
1438 | return child; | 1423 | return child; |
1439 | } | 1424 | } |
1425 | EXPORT_SYMBOL_GPL(device_find_child); | ||
1440 | 1426 | ||
1441 | int __init devices_init(void) | 1427 | int __init devices_init(void) |
1442 | { | 1428 | { |
@@ -1464,21 +1450,6 @@ int __init devices_init(void) | |||
1464 | return -ENOMEM; | 1450 | return -ENOMEM; |
1465 | } | 1451 | } |
1466 | 1452 | ||
1467 | EXPORT_SYMBOL_GPL(device_for_each_child); | ||
1468 | EXPORT_SYMBOL_GPL(device_find_child); | ||
1469 | |||
1470 | EXPORT_SYMBOL_GPL(device_initialize); | ||
1471 | EXPORT_SYMBOL_GPL(device_add); | ||
1472 | EXPORT_SYMBOL_GPL(device_register); | ||
1473 | |||
1474 | EXPORT_SYMBOL_GPL(device_del); | ||
1475 | EXPORT_SYMBOL_GPL(device_unregister); | ||
1476 | EXPORT_SYMBOL_GPL(get_device); | ||
1477 | EXPORT_SYMBOL_GPL(put_device); | ||
1478 | |||
1479 | EXPORT_SYMBOL_GPL(device_create_file); | ||
1480 | EXPORT_SYMBOL_GPL(device_remove_file); | ||
1481 | |||
1482 | static DEFINE_MUTEX(device_hotplug_lock); | 1453 | static DEFINE_MUTEX(device_hotplug_lock); |
1483 | 1454 | ||
1484 | void lock_device_hotplug(void) | 1455 | void lock_device_hotplug(void) |
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index 4c358bc44c72..6bfaaca6955e 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c | |||
@@ -43,11 +43,14 @@ static int __ref cpu_subsys_online(struct device *dev) | |||
43 | struct cpu *cpu = container_of(dev, struct cpu, dev); | 43 | struct cpu *cpu = container_of(dev, struct cpu, dev); |
44 | int cpuid = dev->id; | 44 | int cpuid = dev->id; |
45 | int from_nid, to_nid; | 45 | int from_nid, to_nid; |
46 | int ret; | 46 | int ret = -ENODEV; |
47 | 47 | ||
48 | cpu_hotplug_driver_lock(); | 48 | cpu_hotplug_driver_lock(); |
49 | 49 | ||
50 | from_nid = cpu_to_node(cpuid); | 50 | from_nid = cpu_to_node(cpuid); |
51 | if (from_nid == NUMA_NO_NODE) | ||
52 | goto out; | ||
53 | |||
51 | ret = cpu_up(cpuid); | 54 | ret = cpu_up(cpuid); |
52 | /* | 55 | /* |
53 | * When hot adding memory to memoryless node and enabling a cpu | 56 | * When hot adding memory to memoryless node and enabling a cpu |
@@ -57,6 +60,7 @@ static int __ref cpu_subsys_online(struct device *dev) | |||
57 | if (from_nid != to_nid) | 60 | if (from_nid != to_nid) |
58 | change_cpu_under_node(cpu, from_nid, to_nid); | 61 | change_cpu_under_node(cpu, from_nid, to_nid); |
59 | 62 | ||
63 | out: | ||
60 | cpu_hotplug_driver_unlock(); | 64 | cpu_hotplug_driver_unlock(); |
61 | return ret; | 65 | return ret; |
62 | } | 66 | } |
diff --git a/drivers/base/dma-contiguous.c b/drivers/base/dma-contiguous.c index 0ca54421ce97..6c9cdaa9200d 100644 --- a/drivers/base/dma-contiguous.c +++ b/drivers/base/dma-contiguous.c | |||
@@ -134,7 +134,7 @@ void __init dma_contiguous_reserve(phys_addr_t limit) | |||
134 | 134 | ||
135 | static DEFINE_MUTEX(cma_mutex); | 135 | static DEFINE_MUTEX(cma_mutex); |
136 | 136 | ||
137 | static __init int cma_activate_area(unsigned long base_pfn, unsigned long count) | 137 | static int __init cma_activate_area(unsigned long base_pfn, unsigned long count) |
138 | { | 138 | { |
139 | unsigned long pfn = base_pfn; | 139 | unsigned long pfn = base_pfn; |
140 | unsigned i = count >> pageblock_order; | 140 | unsigned i = count >> pageblock_order; |
@@ -156,7 +156,7 @@ static __init int cma_activate_area(unsigned long base_pfn, unsigned long count) | |||
156 | return 0; | 156 | return 0; |
157 | } | 157 | } |
158 | 158 | ||
159 | static __init struct cma *cma_create_area(unsigned long base_pfn, | 159 | static struct cma * __init cma_create_area(unsigned long base_pfn, |
160 | unsigned long count) | 160 | unsigned long count) |
161 | { | 161 | { |
162 | int bitmap_size = BITS_TO_LONGS(count) * sizeof(long); | 162 | int bitmap_size = BITS_TO_LONGS(count) * sizeof(long); |
diff --git a/drivers/base/driver.c b/drivers/base/driver.c index 974e301a1ef0..9e29943e56ca 100644 --- a/drivers/base/driver.c +++ b/drivers/base/driver.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/errno.h> | 15 | #include <linux/errno.h> |
16 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
17 | #include <linux/string.h> | 17 | #include <linux/string.h> |
18 | #include <linux/sysfs.h> | ||
18 | #include "base.h" | 19 | #include "base.h" |
19 | 20 | ||
20 | static struct device *next_device(struct klist_iter *i) | 21 | static struct device *next_device(struct klist_iter *i) |
@@ -123,34 +124,16 @@ void driver_remove_file(struct device_driver *drv, | |||
123 | } | 124 | } |
124 | EXPORT_SYMBOL_GPL(driver_remove_file); | 125 | EXPORT_SYMBOL_GPL(driver_remove_file); |
125 | 126 | ||
126 | static int driver_add_groups(struct device_driver *drv, | 127 | int driver_add_groups(struct device_driver *drv, |
127 | const struct attribute_group **groups) | 128 | const struct attribute_group **groups) |
128 | { | 129 | { |
129 | int error = 0; | 130 | return sysfs_create_groups(&drv->p->kobj, groups); |
130 | int i; | ||
131 | |||
132 | if (groups) { | ||
133 | for (i = 0; groups[i]; i++) { | ||
134 | error = sysfs_create_group(&drv->p->kobj, groups[i]); | ||
135 | if (error) { | ||
136 | while (--i >= 0) | ||
137 | sysfs_remove_group(&drv->p->kobj, | ||
138 | groups[i]); | ||
139 | break; | ||
140 | } | ||
141 | } | ||
142 | } | ||
143 | return error; | ||
144 | } | 131 | } |
145 | 132 | ||
146 | static void driver_remove_groups(struct device_driver *drv, | 133 | void driver_remove_groups(struct device_driver *drv, |
147 | const struct attribute_group **groups) | 134 | const struct attribute_group **groups) |
148 | { | 135 | { |
149 | int i; | 136 | sysfs_remove_groups(&drv->p->kobj, groups); |
150 | |||
151 | if (groups) | ||
152 | for (i = 0; groups[i]; i++) | ||
153 | sysfs_remove_group(&drv->p->kobj, groups[i]); | ||
154 | } | 137 | } |
155 | 138 | ||
156 | /** | 139 | /** |
diff --git a/drivers/base/firmware_class.c b/drivers/base/firmware_class.c index a439602ea919..10a4467c63f1 100644 --- a/drivers/base/firmware_class.c +++ b/drivers/base/firmware_class.c | |||
@@ -486,9 +486,8 @@ static struct notifier_block fw_shutdown_nb = { | |||
486 | .notifier_call = fw_shutdown_notify, | 486 | .notifier_call = fw_shutdown_notify, |
487 | }; | 487 | }; |
488 | 488 | ||
489 | static ssize_t firmware_timeout_show(struct class *class, | 489 | static ssize_t timeout_show(struct class *class, struct class_attribute *attr, |
490 | struct class_attribute *attr, | 490 | char *buf) |
491 | char *buf) | ||
492 | { | 491 | { |
493 | return sprintf(buf, "%d\n", loading_timeout); | 492 | return sprintf(buf, "%d\n", loading_timeout); |
494 | } | 493 | } |
@@ -506,9 +505,8 @@ static ssize_t firmware_timeout_show(struct class *class, | |||
506 | * | 505 | * |
507 | * Note: zero means 'wait forever'. | 506 | * Note: zero means 'wait forever'. |
508 | **/ | 507 | **/ |
509 | static ssize_t firmware_timeout_store(struct class *class, | 508 | static ssize_t timeout_store(struct class *class, struct class_attribute *attr, |
510 | struct class_attribute *attr, | 509 | const char *buf, size_t count) |
511 | const char *buf, size_t count) | ||
512 | { | 510 | { |
513 | loading_timeout = simple_strtol(buf, NULL, 10); | 511 | loading_timeout = simple_strtol(buf, NULL, 10); |
514 | if (loading_timeout < 0) | 512 | if (loading_timeout < 0) |
@@ -518,8 +516,7 @@ static ssize_t firmware_timeout_store(struct class *class, | |||
518 | } | 516 | } |
519 | 517 | ||
520 | static struct class_attribute firmware_class_attrs[] = { | 518 | static struct class_attribute firmware_class_attrs[] = { |
521 | __ATTR(timeout, S_IWUSR | S_IRUGO, | 519 | __ATTR_RW(timeout), |
522 | firmware_timeout_show, firmware_timeout_store), | ||
523 | __ATTR_NULL | 520 | __ATTR_NULL |
524 | }; | 521 | }; |
525 | 522 | ||
@@ -868,8 +865,15 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
868 | goto err_del_dev; | 865 | goto err_del_dev; |
869 | } | 866 | } |
870 | 867 | ||
868 | mutex_lock(&fw_lock); | ||
869 | list_add(&buf->pending_list, &pending_fw_head); | ||
870 | mutex_unlock(&fw_lock); | ||
871 | |||
871 | retval = device_create_file(f_dev, &dev_attr_loading); | 872 | retval = device_create_file(f_dev, &dev_attr_loading); |
872 | if (retval) { | 873 | if (retval) { |
874 | mutex_lock(&fw_lock); | ||
875 | list_del_init(&buf->pending_list); | ||
876 | mutex_unlock(&fw_lock); | ||
873 | dev_err(f_dev, "%s: device_create_file failed\n", __func__); | 877 | dev_err(f_dev, "%s: device_create_file failed\n", __func__); |
874 | goto err_del_bin_attr; | 878 | goto err_del_bin_attr; |
875 | } | 879 | } |
@@ -884,10 +888,6 @@ static int _request_firmware_load(struct firmware_priv *fw_priv, bool uevent, | |||
884 | kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); | 888 | kobject_uevent(&fw_priv->dev.kobj, KOBJ_ADD); |
885 | } | 889 | } |
886 | 890 | ||
887 | mutex_lock(&fw_lock); | ||
888 | list_add(&buf->pending_list, &pending_fw_head); | ||
889 | mutex_unlock(&fw_lock); | ||
890 | |||
891 | wait_for_completion(&buf->completion); | 891 | wait_for_completion(&buf->completion); |
892 | 892 | ||
893 | cancel_delayed_work_sync(&fw_priv->timeout_work); | 893 | cancel_delayed_work_sync(&fw_priv->timeout_work); |
diff --git a/drivers/base/memory.c b/drivers/base/memory.c index ec386ee9cb22..1c617623c8ae 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c | |||
@@ -16,7 +16,6 @@ | |||
16 | #include <linux/capability.h> | 16 | #include <linux/capability.h> |
17 | #include <linux/device.h> | 17 | #include <linux/device.h> |
18 | #include <linux/memory.h> | 18 | #include <linux/memory.h> |
19 | #include <linux/kobject.h> | ||
20 | #include <linux/memory_hotplug.h> | 19 | #include <linux/memory_hotplug.h> |
21 | #include <linux/mm.h> | 20 | #include <linux/mm.h> |
22 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
@@ -30,6 +29,8 @@ static DEFINE_MUTEX(mem_sysfs_mutex); | |||
30 | 29 | ||
31 | #define MEMORY_CLASS_NAME "memory" | 30 | #define MEMORY_CLASS_NAME "memory" |
32 | 31 | ||
32 | #define to_memory_block(dev) container_of(dev, struct memory_block, dev) | ||
33 | |||
33 | static int sections_per_block; | 34 | static int sections_per_block; |
34 | 35 | ||
35 | static inline int base_memory_block_id(int section_nr) | 36 | static inline int base_memory_block_id(int section_nr) |
@@ -77,7 +78,7 @@ EXPORT_SYMBOL(unregister_memory_isolate_notifier); | |||
77 | 78 | ||
78 | static void memory_block_release(struct device *dev) | 79 | static void memory_block_release(struct device *dev) |
79 | { | 80 | { |
80 | struct memory_block *mem = container_of(dev, struct memory_block, dev); | 81 | struct memory_block *mem = to_memory_block(dev); |
81 | 82 | ||
82 | kfree(mem); | 83 | kfree(mem); |
83 | } | 84 | } |
@@ -110,8 +111,7 @@ static unsigned long get_memory_block_size(void) | |||
110 | static ssize_t show_mem_start_phys_index(struct device *dev, | 111 | static ssize_t show_mem_start_phys_index(struct device *dev, |
111 | struct device_attribute *attr, char *buf) | 112 | struct device_attribute *attr, char *buf) |
112 | { | 113 | { |
113 | struct memory_block *mem = | 114 | struct memory_block *mem = to_memory_block(dev); |
114 | container_of(dev, struct memory_block, dev); | ||
115 | unsigned long phys_index; | 115 | unsigned long phys_index; |
116 | 116 | ||
117 | phys_index = mem->start_section_nr / sections_per_block; | 117 | phys_index = mem->start_section_nr / sections_per_block; |
@@ -121,8 +121,7 @@ static ssize_t show_mem_start_phys_index(struct device *dev, | |||
121 | static ssize_t show_mem_end_phys_index(struct device *dev, | 121 | static ssize_t show_mem_end_phys_index(struct device *dev, |
122 | struct device_attribute *attr, char *buf) | 122 | struct device_attribute *attr, char *buf) |
123 | { | 123 | { |
124 | struct memory_block *mem = | 124 | struct memory_block *mem = to_memory_block(dev); |
125 | container_of(dev, struct memory_block, dev); | ||
126 | unsigned long phys_index; | 125 | unsigned long phys_index; |
127 | 126 | ||
128 | phys_index = mem->end_section_nr / sections_per_block; | 127 | phys_index = mem->end_section_nr / sections_per_block; |
@@ -137,8 +136,7 @@ static ssize_t show_mem_removable(struct device *dev, | |||
137 | { | 136 | { |
138 | unsigned long i, pfn; | 137 | unsigned long i, pfn; |
139 | int ret = 1; | 138 | int ret = 1; |
140 | struct memory_block *mem = | 139 | struct memory_block *mem = to_memory_block(dev); |
141 | container_of(dev, struct memory_block, dev); | ||
142 | 140 | ||
143 | for (i = 0; i < sections_per_block; i++) { | 141 | for (i = 0; i < sections_per_block; i++) { |
144 | if (!present_section_nr(mem->start_section_nr + i)) | 142 | if (!present_section_nr(mem->start_section_nr + i)) |
@@ -156,8 +154,7 @@ static ssize_t show_mem_removable(struct device *dev, | |||
156 | static ssize_t show_mem_state(struct device *dev, | 154 | static ssize_t show_mem_state(struct device *dev, |
157 | struct device_attribute *attr, char *buf) | 155 | struct device_attribute *attr, char *buf) |
158 | { | 156 | { |
159 | struct memory_block *mem = | 157 | struct memory_block *mem = to_memory_block(dev); |
160 | container_of(dev, struct memory_block, dev); | ||
161 | ssize_t len = 0; | 158 | ssize_t len = 0; |
162 | 159 | ||
163 | /* | 160 | /* |
@@ -263,9 +260,8 @@ memory_block_action(unsigned long phys_index, unsigned long action, int online_t | |||
263 | return ret; | 260 | return ret; |
264 | } | 261 | } |
265 | 262 | ||
266 | static int __memory_block_change_state(struct memory_block *mem, | 263 | static int memory_block_change_state(struct memory_block *mem, |
267 | unsigned long to_state, unsigned long from_state_req, | 264 | unsigned long to_state, unsigned long from_state_req) |
268 | int online_type) | ||
269 | { | 265 | { |
270 | int ret = 0; | 266 | int ret = 0; |
271 | 267 | ||
@@ -275,105 +271,89 @@ static int __memory_block_change_state(struct memory_block *mem, | |||
275 | if (to_state == MEM_OFFLINE) | 271 | if (to_state == MEM_OFFLINE) |
276 | mem->state = MEM_GOING_OFFLINE; | 272 | mem->state = MEM_GOING_OFFLINE; |
277 | 273 | ||
278 | ret = memory_block_action(mem->start_section_nr, to_state, online_type); | 274 | ret = memory_block_action(mem->start_section_nr, to_state, |
275 | mem->online_type); | ||
276 | |||
279 | mem->state = ret ? from_state_req : to_state; | 277 | mem->state = ret ? from_state_req : to_state; |
278 | |||
280 | return ret; | 279 | return ret; |
281 | } | 280 | } |
282 | 281 | ||
282 | /* The device lock serializes operations on memory_subsys_[online|offline] */ | ||
283 | static int memory_subsys_online(struct device *dev) | 283 | static int memory_subsys_online(struct device *dev) |
284 | { | 284 | { |
285 | struct memory_block *mem = container_of(dev, struct memory_block, dev); | 285 | struct memory_block *mem = to_memory_block(dev); |
286 | int ret; | 286 | int ret; |
287 | 287 | ||
288 | mutex_lock(&mem->state_mutex); | 288 | if (mem->state == MEM_ONLINE) |
289 | 289 | return 0; | |
290 | ret = mem->state == MEM_ONLINE ? 0 : | ||
291 | __memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE, | ||
292 | ONLINE_KEEP); | ||
293 | 290 | ||
294 | mutex_unlock(&mem->state_mutex); | 291 | /* |
295 | return ret; | 292 | * If we are called from store_mem_state(), online_type will be |
296 | } | 293 | * set >= 0 Otherwise we were called from the device online |
297 | 294 | * attribute and need to set the online_type. | |
298 | static int memory_subsys_offline(struct device *dev) | 295 | */ |
299 | { | 296 | if (mem->online_type < 0) |
300 | struct memory_block *mem = container_of(dev, struct memory_block, dev); | 297 | mem->online_type = ONLINE_KEEP; |
301 | int ret; | ||
302 | 298 | ||
303 | mutex_lock(&mem->state_mutex); | 299 | ret = memory_block_change_state(mem, MEM_ONLINE, MEM_OFFLINE); |
304 | 300 | ||
305 | ret = mem->state == MEM_OFFLINE ? 0 : | 301 | /* clear online_type */ |
306 | __memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE, -1); | 302 | mem->online_type = -1; |
307 | 303 | ||
308 | mutex_unlock(&mem->state_mutex); | ||
309 | return ret; | 304 | return ret; |
310 | } | 305 | } |
311 | 306 | ||
312 | static int __memory_block_change_state_uevent(struct memory_block *mem, | 307 | static int memory_subsys_offline(struct device *dev) |
313 | unsigned long to_state, unsigned long from_state_req, | ||
314 | int online_type) | ||
315 | { | ||
316 | int ret = __memory_block_change_state(mem, to_state, from_state_req, | ||
317 | online_type); | ||
318 | if (!ret) { | ||
319 | switch (mem->state) { | ||
320 | case MEM_OFFLINE: | ||
321 | kobject_uevent(&mem->dev.kobj, KOBJ_OFFLINE); | ||
322 | break; | ||
323 | case MEM_ONLINE: | ||
324 | kobject_uevent(&mem->dev.kobj, KOBJ_ONLINE); | ||
325 | break; | ||
326 | default: | ||
327 | break; | ||
328 | } | ||
329 | } | ||
330 | return ret; | ||
331 | } | ||
332 | |||
333 | static int memory_block_change_state(struct memory_block *mem, | ||
334 | unsigned long to_state, unsigned long from_state_req, | ||
335 | int online_type) | ||
336 | { | 308 | { |
337 | int ret; | 309 | struct memory_block *mem = to_memory_block(dev); |
338 | 310 | ||
339 | mutex_lock(&mem->state_mutex); | 311 | if (mem->state == MEM_OFFLINE) |
340 | ret = __memory_block_change_state_uevent(mem, to_state, from_state_req, | 312 | return 0; |
341 | online_type); | ||
342 | mutex_unlock(&mem->state_mutex); | ||
343 | 313 | ||
344 | return ret; | 314 | return memory_block_change_state(mem, MEM_OFFLINE, MEM_ONLINE); |
345 | } | 315 | } |
316 | |||
346 | static ssize_t | 317 | static ssize_t |
347 | store_mem_state(struct device *dev, | 318 | store_mem_state(struct device *dev, |
348 | struct device_attribute *attr, const char *buf, size_t count) | 319 | struct device_attribute *attr, const char *buf, size_t count) |
349 | { | 320 | { |
350 | struct memory_block *mem; | 321 | struct memory_block *mem = to_memory_block(dev); |
351 | bool offline; | 322 | int ret, online_type; |
352 | int ret = -EINVAL; | ||
353 | |||
354 | mem = container_of(dev, struct memory_block, dev); | ||
355 | 323 | ||
356 | lock_device_hotplug(); | 324 | lock_device_hotplug(); |
357 | 325 | ||
358 | if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) { | 326 | if (!strncmp(buf, "online_kernel", min_t(int, count, 13))) |
359 | offline = false; | 327 | online_type = ONLINE_KERNEL; |
360 | ret = memory_block_change_state(mem, MEM_ONLINE, | 328 | else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) |
361 | MEM_OFFLINE, ONLINE_KERNEL); | 329 | online_type = ONLINE_MOVABLE; |
362 | } else if (!strncmp(buf, "online_movable", min_t(int, count, 14))) { | 330 | else if (!strncmp(buf, "online", min_t(int, count, 6))) |
363 | offline = false; | 331 | online_type = ONLINE_KEEP; |
364 | ret = memory_block_change_state(mem, MEM_ONLINE, | 332 | else if (!strncmp(buf, "offline", min_t(int, count, 7))) |
365 | MEM_OFFLINE, ONLINE_MOVABLE); | 333 | online_type = -1; |
366 | } else if (!strncmp(buf, "online", min_t(int, count, 6))) { | 334 | else |
367 | offline = false; | 335 | return -EINVAL; |
368 | ret = memory_block_change_state(mem, MEM_ONLINE, | 336 | |
369 | MEM_OFFLINE, ONLINE_KEEP); | 337 | switch (online_type) { |
370 | } else if(!strncmp(buf, "offline", min_t(int, count, 7))) { | 338 | case ONLINE_KERNEL: |
371 | offline = true; | 339 | case ONLINE_MOVABLE: |
372 | ret = memory_block_change_state(mem, MEM_OFFLINE, | 340 | case ONLINE_KEEP: |
373 | MEM_ONLINE, -1); | 341 | /* |
342 | * mem->online_type is not protected so there can be a | ||
343 | * race here. However, when racing online, the first | ||
344 | * will succeed and the second will just return as the | ||
345 | * block will already be online. The online type | ||
346 | * could be either one, but that is expected. | ||
347 | */ | ||
348 | mem->online_type = online_type; | ||
349 | ret = device_online(&mem->dev); | ||
350 | break; | ||
351 | case -1: | ||
352 | ret = device_offline(&mem->dev); | ||
353 | break; | ||
354 | default: | ||
355 | ret = -EINVAL; /* should never happen */ | ||
374 | } | 356 | } |
375 | if (!ret) | ||
376 | dev->offline = offline; | ||
377 | 357 | ||
378 | unlock_device_hotplug(); | 358 | unlock_device_hotplug(); |
379 | 359 | ||
@@ -394,8 +374,7 @@ store_mem_state(struct device *dev, | |||
394 | static ssize_t show_phys_device(struct device *dev, | 374 | static ssize_t show_phys_device(struct device *dev, |
395 | struct device_attribute *attr, char *buf) | 375 | struct device_attribute *attr, char *buf) |
396 | { | 376 | { |
397 | struct memory_block *mem = | 377 | struct memory_block *mem = to_memory_block(dev); |
398 | container_of(dev, struct memory_block, dev); | ||
399 | return sprintf(buf, "%d\n", mem->phys_device); | 378 | return sprintf(buf, "%d\n", mem->phys_device); |
400 | } | 379 | } |
401 | 380 | ||
@@ -471,7 +450,7 @@ store_soft_offline_page(struct device *dev, | |||
471 | u64 pfn; | 450 | u64 pfn; |
472 | if (!capable(CAP_SYS_ADMIN)) | 451 | if (!capable(CAP_SYS_ADMIN)) |
473 | return -EPERM; | 452 | return -EPERM; |
474 | if (strict_strtoull(buf, 0, &pfn) < 0) | 453 | if (kstrtoull(buf, 0, &pfn) < 0) |
475 | return -EINVAL; | 454 | return -EINVAL; |
476 | pfn >>= PAGE_SHIFT; | 455 | pfn >>= PAGE_SHIFT; |
477 | if (!pfn_valid(pfn)) | 456 | if (!pfn_valid(pfn)) |
@@ -490,7 +469,7 @@ store_hard_offline_page(struct device *dev, | |||
490 | u64 pfn; | 469 | u64 pfn; |
491 | if (!capable(CAP_SYS_ADMIN)) | 470 | if (!capable(CAP_SYS_ADMIN)) |
492 | return -EPERM; | 471 | return -EPERM; |
493 | if (strict_strtoull(buf, 0, &pfn) < 0) | 472 | if (kstrtoull(buf, 0, &pfn) < 0) |
494 | return -EINVAL; | 473 | return -EINVAL; |
495 | pfn >>= PAGE_SHIFT; | 474 | pfn >>= PAGE_SHIFT; |
496 | ret = memory_failure(pfn, 0, 0); | 475 | ret = memory_failure(pfn, 0, 0); |
@@ -527,7 +506,7 @@ struct memory_block *find_memory_block_hinted(struct mem_section *section, | |||
527 | put_device(&hint->dev); | 506 | put_device(&hint->dev); |
528 | if (!dev) | 507 | if (!dev) |
529 | return NULL; | 508 | return NULL; |
530 | return container_of(dev, struct memory_block, dev); | 509 | return to_memory_block(dev); |
531 | } | 510 | } |
532 | 511 | ||
533 | /* | 512 | /* |
@@ -567,16 +546,13 @@ static const struct attribute_group *memory_memblk_attr_groups[] = { | |||
567 | static | 546 | static |
568 | int register_memory(struct memory_block *memory) | 547 | int register_memory(struct memory_block *memory) |
569 | { | 548 | { |
570 | int error; | ||
571 | |||
572 | memory->dev.bus = &memory_subsys; | 549 | memory->dev.bus = &memory_subsys; |
573 | memory->dev.id = memory->start_section_nr / sections_per_block; | 550 | memory->dev.id = memory->start_section_nr / sections_per_block; |
574 | memory->dev.release = memory_block_release; | 551 | memory->dev.release = memory_block_release; |
575 | memory->dev.groups = memory_memblk_attr_groups; | 552 | memory->dev.groups = memory_memblk_attr_groups; |
576 | memory->dev.offline = memory->state == MEM_OFFLINE; | 553 | memory->dev.offline = memory->state == MEM_OFFLINE; |
577 | 554 | ||
578 | error = device_register(&memory->dev); | 555 | return device_register(&memory->dev); |
579 | return error; | ||
580 | } | 556 | } |
581 | 557 | ||
582 | static int init_memory_block(struct memory_block **memory, | 558 | static int init_memory_block(struct memory_block **memory, |
@@ -597,7 +573,6 @@ static int init_memory_block(struct memory_block **memory, | |||
597 | mem->end_section_nr = mem->start_section_nr + sections_per_block - 1; | 573 | mem->end_section_nr = mem->start_section_nr + sections_per_block - 1; |
598 | mem->state = state; | 574 | mem->state = state; |
599 | mem->section_count++; | 575 | mem->section_count++; |
600 | mutex_init(&mem->state_mutex); | ||
601 | start_pfn = section_nr_to_pfn(mem->start_section_nr); | 576 | start_pfn = section_nr_to_pfn(mem->start_section_nr); |
602 | mem->phys_device = arch_get_memory_phys_device(start_pfn); | 577 | mem->phys_device = arch_get_memory_phys_device(start_pfn); |
603 | 578 | ||
@@ -607,55 +582,57 @@ static int init_memory_block(struct memory_block **memory, | |||
607 | return ret; | 582 | return ret; |
608 | } | 583 | } |
609 | 584 | ||
610 | static int add_memory_section(int nid, struct mem_section *section, | 585 | static int add_memory_block(int base_section_nr) |
611 | struct memory_block **mem_p, | ||
612 | unsigned long state, enum mem_add_context context) | ||
613 | { | 586 | { |
614 | struct memory_block *mem = NULL; | 587 | struct memory_block *mem; |
615 | int scn_nr = __section_nr(section); | 588 | int i, ret, section_count = 0, section_nr; |
616 | int ret = 0; | ||
617 | |||
618 | mutex_lock(&mem_sysfs_mutex); | ||
619 | |||
620 | if (context == BOOT) { | ||
621 | /* same memory block ? */ | ||
622 | if (mem_p && *mem_p) | ||
623 | if (scn_nr >= (*mem_p)->start_section_nr && | ||
624 | scn_nr <= (*mem_p)->end_section_nr) { | ||
625 | mem = *mem_p; | ||
626 | kobject_get(&mem->dev.kobj); | ||
627 | } | ||
628 | } else | ||
629 | mem = find_memory_block(section); | ||
630 | |||
631 | if (mem) { | ||
632 | mem->section_count++; | ||
633 | kobject_put(&mem->dev.kobj); | ||
634 | } else { | ||
635 | ret = init_memory_block(&mem, section, state); | ||
636 | /* store memory_block pointer for next loop */ | ||
637 | if (!ret && context == BOOT) | ||
638 | if (mem_p) | ||
639 | *mem_p = mem; | ||
640 | } | ||
641 | 589 | ||
642 | if (!ret) { | 590 | for (i = base_section_nr; |
643 | if (context == HOTPLUG && | 591 | (i < base_section_nr + sections_per_block) && i < NR_MEM_SECTIONS; |
644 | mem->section_count == sections_per_block) | 592 | i++) { |
645 | ret = register_mem_sect_under_node(mem, nid); | 593 | if (!present_section_nr(i)) |
594 | continue; | ||
595 | if (section_count == 0) | ||
596 | section_nr = i; | ||
597 | section_count++; | ||
646 | } | 598 | } |
647 | 599 | ||
648 | mutex_unlock(&mem_sysfs_mutex); | 600 | if (section_count == 0) |
649 | return ret; | 601 | return 0; |
602 | ret = init_memory_block(&mem, __nr_to_section(section_nr), MEM_ONLINE); | ||
603 | if (ret) | ||
604 | return ret; | ||
605 | mem->section_count = section_count; | ||
606 | return 0; | ||
650 | } | 607 | } |
651 | 608 | ||
609 | |||
652 | /* | 610 | /* |
653 | * need an interface for the VM to add new memory regions, | 611 | * need an interface for the VM to add new memory regions, |
654 | * but without onlining it. | 612 | * but without onlining it. |
655 | */ | 613 | */ |
656 | int register_new_memory(int nid, struct mem_section *section) | 614 | int register_new_memory(int nid, struct mem_section *section) |
657 | { | 615 | { |
658 | return add_memory_section(nid, section, NULL, MEM_OFFLINE, HOTPLUG); | 616 | int ret = 0; |
617 | struct memory_block *mem; | ||
618 | |||
619 | mutex_lock(&mem_sysfs_mutex); | ||
620 | |||
621 | mem = find_memory_block(section); | ||
622 | if (mem) { | ||
623 | mem->section_count++; | ||
624 | put_device(&mem->dev); | ||
625 | } else { | ||
626 | ret = init_memory_block(&mem, section, MEM_OFFLINE); | ||
627 | if (ret) | ||
628 | goto out; | ||
629 | } | ||
630 | |||
631 | if (mem->section_count == sections_per_block) | ||
632 | ret = register_mem_sect_under_node(mem, nid); | ||
633 | out: | ||
634 | mutex_unlock(&mem_sysfs_mutex); | ||
635 | return ret; | ||
659 | } | 636 | } |
660 | 637 | ||
661 | #ifdef CONFIG_MEMORY_HOTREMOVE | 638 | #ifdef CONFIG_MEMORY_HOTREMOVE |
@@ -665,7 +642,7 @@ unregister_memory(struct memory_block *memory) | |||
665 | BUG_ON(memory->dev.bus != &memory_subsys); | 642 | BUG_ON(memory->dev.bus != &memory_subsys); |
666 | 643 | ||
667 | /* drop the ref. we got in remove_memory_block() */ | 644 | /* drop the ref. we got in remove_memory_block() */ |
668 | kobject_put(&memory->dev.kobj); | 645 | put_device(&memory->dev); |
669 | device_unregister(&memory->dev); | 646 | device_unregister(&memory->dev); |
670 | } | 647 | } |
671 | 648 | ||
@@ -682,7 +659,7 @@ static int remove_memory_block(unsigned long node_id, | |||
682 | if (mem->section_count == 0) | 659 | if (mem->section_count == 0) |
683 | unregister_memory(mem); | 660 | unregister_memory(mem); |
684 | else | 661 | else |
685 | kobject_put(&mem->dev.kobj); | 662 | put_device(&mem->dev); |
686 | 663 | ||
687 | mutex_unlock(&mem_sysfs_mutex); | 664 | mutex_unlock(&mem_sysfs_mutex); |
688 | return 0; | 665 | return 0; |
@@ -735,7 +712,6 @@ int __init memory_dev_init(void) | |||
735 | int ret; | 712 | int ret; |
736 | int err; | 713 | int err; |
737 | unsigned long block_sz; | 714 | unsigned long block_sz; |
738 | struct memory_block *mem = NULL; | ||
739 | 715 | ||
740 | ret = subsys_system_register(&memory_subsys, memory_root_attr_groups); | 716 | ret = subsys_system_register(&memory_subsys, memory_root_attr_groups); |
741 | if (ret) | 717 | if (ret) |
@@ -748,17 +724,13 @@ int __init memory_dev_init(void) | |||
748 | * Create entries for memory sections that were found | 724 | * Create entries for memory sections that were found |
749 | * during boot and have been initialized | 725 | * during boot and have been initialized |
750 | */ | 726 | */ |
751 | for (i = 0; i < NR_MEM_SECTIONS; i++) { | 727 | mutex_lock(&mem_sysfs_mutex); |
752 | if (!present_section_nr(i)) | 728 | for (i = 0; i < NR_MEM_SECTIONS; i += sections_per_block) { |
753 | continue; | 729 | err = add_memory_block(i); |
754 | /* don't need to reuse memory_block if only one per block */ | ||
755 | err = add_memory_section(0, __nr_to_section(i), | ||
756 | (sections_per_block == 1) ? NULL : &mem, | ||
757 | MEM_ONLINE, | ||
758 | BOOT); | ||
759 | if (!ret) | 730 | if (!ret) |
760 | ret = err; | 731 | ret = err; |
761 | } | 732 | } |
733 | mutex_unlock(&mem_sysfs_mutex); | ||
762 | 734 | ||
763 | out: | 735 | out: |
764 | if (ret) | 736 | if (ret) |
diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 3c3197a8de41..4f8bef3eb5a8 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c | |||
@@ -672,11 +672,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | |||
672 | 672 | ||
673 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 673 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
674 | } | 674 | } |
675 | static DEVICE_ATTR_RO(modalias); | ||
675 | 676 | ||
676 | static struct device_attribute platform_dev_attrs[] = { | 677 | static struct attribute *platform_dev_attrs[] = { |
677 | __ATTR_RO(modalias), | 678 | &dev_attr_modalias.attr, |
678 | __ATTR_NULL, | 679 | NULL, |
679 | }; | 680 | }; |
681 | ATTRIBUTE_GROUPS(platform_dev); | ||
680 | 682 | ||
681 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) | 683 | static int platform_uevent(struct device *dev, struct kobj_uevent_env *env) |
682 | { | 684 | { |
@@ -893,7 +895,7 @@ static const struct dev_pm_ops platform_dev_pm_ops = { | |||
893 | 895 | ||
894 | struct bus_type platform_bus_type = { | 896 | struct bus_type platform_bus_type = { |
895 | .name = "platform", | 897 | .name = "platform", |
896 | .dev_attrs = platform_dev_attrs, | 898 | .dev_groups = platform_dev_groups, |
897 | .match = platform_match, | 899 | .match = platform_match, |
898 | .uevent = platform_uevent, | 900 | .uevent = platform_uevent, |
899 | .pm = &platform_dev_pm_ops, | 901 | .pm = &platform_dev_pm_ops, |
@@ -1054,7 +1056,7 @@ void __init early_platform_driver_register_all(char *class_str) | |||
1054 | * @epdrv: early platform driver structure | 1056 | * @epdrv: early platform driver structure |
1055 | * @id: id to match against | 1057 | * @id: id to match against |
1056 | */ | 1058 | */ |
1057 | static __init struct platform_device * | 1059 | static struct platform_device * __init |
1058 | early_platform_match(struct early_platform_driver *epdrv, int id) | 1060 | early_platform_match(struct early_platform_driver *epdrv, int id) |
1059 | { | 1061 | { |
1060 | struct platform_device *pd; | 1062 | struct platform_device *pd; |
@@ -1072,7 +1074,7 @@ early_platform_match(struct early_platform_driver *epdrv, int id) | |||
1072 | * @epdrv: early platform driver structure | 1074 | * @epdrv: early platform driver structure |
1073 | * @id: return true if id or above exists | 1075 | * @id: return true if id or above exists |
1074 | */ | 1076 | */ |
1075 | static __init int early_platform_left(struct early_platform_driver *epdrv, | 1077 | static int __init early_platform_left(struct early_platform_driver *epdrv, |
1076 | int id) | 1078 | int id) |
1077 | { | 1079 | { |
1078 | struct platform_device *pd; | 1080 | struct platform_device *pd; |
diff --git a/drivers/base/power/sysfs.c b/drivers/base/power/sysfs.c index a53ebd265701..03e089ade5ce 100644 --- a/drivers/base/power/sysfs.c +++ b/drivers/base/power/sysfs.c | |||
@@ -206,7 +206,7 @@ static ssize_t autosuspend_delay_ms_store(struct device *dev, | |||
206 | if (!dev->power.use_autosuspend) | 206 | if (!dev->power.use_autosuspend) |
207 | return -EIO; | 207 | return -EIO; |
208 | 208 | ||
209 | if (strict_strtol(buf, 10, &delay) != 0 || delay != (int) delay) | 209 | if (kstrtol(buf, 10, &delay) != 0 || delay != (int) delay) |
210 | return -EINVAL; | 210 | return -EINVAL; |
211 | 211 | ||
212 | device_lock(dev); | 212 | device_lock(dev); |
diff --git a/drivers/base/regmap/regmap-debugfs.c b/drivers/base/regmap/regmap-debugfs.c index 6c2652a8ad50..de11ecaf3833 100644 --- a/drivers/base/regmap/regmap-debugfs.c +++ b/drivers/base/regmap/regmap-debugfs.c | |||
@@ -281,7 +281,7 @@ static ssize_t regmap_map_write_file(struct file *file, | |||
281 | reg = simple_strtoul(start, &start, 16); | 281 | reg = simple_strtoul(start, &start, 16); |
282 | while (*start == ' ') | 282 | while (*start == ' ') |
283 | start++; | 283 | start++; |
284 | if (strict_strtoul(start, 16, &value)) | 284 | if (kstrtoul(start, 16, &value)) |
285 | return -EINVAL; | 285 | return -EINVAL; |
286 | 286 | ||
287 | /* Userspace has been fiddling around behind the kernel's back */ | 287 | /* Userspace has been fiddling around behind the kernel's back */ |
diff --git a/drivers/base/topology.c b/drivers/base/topology.c index 2f5919ed91ab..94ffee378f10 100644 --- a/drivers/base/topology.c +++ b/drivers/base/topology.c | |||
@@ -62,25 +62,6 @@ static ssize_t show_cpumap(int type, const struct cpumask *mask, char *buf) | |||
62 | } | 62 | } |
63 | #endif | 63 | #endif |
64 | 64 | ||
65 | #ifdef arch_provides_topology_pointers | ||
66 | #define define_siblings_show_map(name) \ | ||
67 | static ssize_t show_##name(struct device *dev, \ | ||
68 | struct device_attribute *attr, char *buf) \ | ||
69 | { \ | ||
70 | unsigned int cpu = dev->id; \ | ||
71 | return show_cpumap(0, topology_##name(cpu), buf); \ | ||
72 | } | ||
73 | |||
74 | #define define_siblings_show_list(name) \ | ||
75 | static ssize_t show_##name##_list(struct device *dev, \ | ||
76 | struct device_attribute *attr, \ | ||
77 | char *buf) \ | ||
78 | { \ | ||
79 | unsigned int cpu = dev->id; \ | ||
80 | return show_cpumap(1, topology_##name(cpu), buf); \ | ||
81 | } | ||
82 | |||
83 | #else | ||
84 | #define define_siblings_show_map(name) \ | 65 | #define define_siblings_show_map(name) \ |
85 | static ssize_t show_##name(struct device *dev, \ | 66 | static ssize_t show_##name(struct device *dev, \ |
86 | struct device_attribute *attr, char *buf) \ | 67 | struct device_attribute *attr, char *buf) \ |
@@ -95,7 +76,6 @@ static ssize_t show_##name##_list(struct device *dev, \ | |||
95 | { \ | 76 | { \ |
96 | return show_cpumap(1, topology_##name(dev->id), buf); \ | 77 | return show_cpumap(1, topology_##name(dev->id), buf); \ |
97 | } | 78 | } |
98 | #endif | ||
99 | 79 | ||
100 | #define define_siblings_show_func(name) \ | 80 | #define define_siblings_show_func(name) \ |
101 | define_siblings_show_map(name); define_siblings_show_list(name) | 81 | define_siblings_show_map(name); define_siblings_show_list(name) |
diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 4ad2ad9a5bb0..191cd177fef2 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c | |||
@@ -397,15 +397,19 @@ static ssize_t rbd_remove(struct bus_type *bus, const char *buf, | |||
397 | static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping); | 397 | static int rbd_dev_image_probe(struct rbd_device *rbd_dev, bool mapping); |
398 | static void rbd_spec_put(struct rbd_spec *spec); | 398 | static void rbd_spec_put(struct rbd_spec *spec); |
399 | 399 | ||
400 | static struct bus_attribute rbd_bus_attrs[] = { | 400 | static BUS_ATTR(add, S_IWUSR, NULL, rbd_add); |
401 | __ATTR(add, S_IWUSR, NULL, rbd_add), | 401 | static BUS_ATTR(remove, S_IWUSR, NULL, rbd_remove); |
402 | __ATTR(remove, S_IWUSR, NULL, rbd_remove), | 402 | |
403 | __ATTR_NULL | 403 | static struct attribute *rbd_bus_attrs[] = { |
404 | &bus_attr_add.attr, | ||
405 | &bus_attr_remove.attr, | ||
406 | NULL, | ||
404 | }; | 407 | }; |
408 | ATTRIBUTE_GROUPS(rbd_bus); | ||
405 | 409 | ||
406 | static struct bus_type rbd_bus_type = { | 410 | static struct bus_type rbd_bus_type = { |
407 | .name = "rbd", | 411 | .name = "rbd", |
408 | .bus_attrs = rbd_bus_attrs, | 412 | .bus_groups = rbd_bus_groups, |
409 | }; | 413 | }; |
410 | 414 | ||
411 | static void rbd_root_dev_release(struct device *dev) | 415 | static void rbd_root_dev_release(struct device *dev) |
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c index 97467053a01b..0671e45daa57 100644 --- a/drivers/char/bsr.c +++ b/drivers/char/bsr.c | |||
@@ -95,6 +95,7 @@ bsr_size_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
95 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); | 95 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); |
96 | return sprintf(buf, "%u\n", bsr_dev->bsr_bytes); | 96 | return sprintf(buf, "%u\n", bsr_dev->bsr_bytes); |
97 | } | 97 | } |
98 | static DEVICE_ATTR_RO(bsr_size); | ||
98 | 99 | ||
99 | static ssize_t | 100 | static ssize_t |
100 | bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf) | 101 | 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) | |||
102 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); | 103 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); |
103 | return sprintf(buf, "%u\n", bsr_dev->bsr_stride); | 104 | return sprintf(buf, "%u\n", bsr_dev->bsr_stride); |
104 | } | 105 | } |
106 | static DEVICE_ATTR_RO(bsr_stride); | ||
105 | 107 | ||
106 | static ssize_t | 108 | static ssize_t |
107 | bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf) | 109 | bsr_length_show(struct device *dev, struct device_attribute *attr, char *buf) |
108 | { | 110 | { |
109 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); | 111 | struct bsr_dev *bsr_dev = dev_get_drvdata(dev); |
110 | return sprintf(buf, "%llu\n", bsr_dev->bsr_len); | 112 | return sprintf(buf, "%llu\n", bsr_dev->bsr_len); |
111 | } | 113 | } |
114 | static DEVICE_ATTR_RO(bsr_length); | ||
112 | 115 | ||
113 | static struct device_attribute bsr_dev_attrs[] = { | 116 | static struct attribute *bsr_dev_attrs[] = { |
114 | __ATTR(bsr_size, S_IRUGO, bsr_size_show, NULL), | 117 | &dev_attr_bsr_size.attr, |
115 | __ATTR(bsr_stride, S_IRUGO, bsr_stride_show, NULL), | 118 | &dev_attr_bsr_stride.attr, |
116 | __ATTR(bsr_length, S_IRUGO, bsr_len_show, NULL), | 119 | &dev_attr_bsr_length.attr, |
117 | __ATTR_NULL | 120 | NULL, |
118 | }; | 121 | }; |
122 | ATTRIBUTE_GROUPS(bsr_dev); | ||
119 | 123 | ||
120 | static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) | 124 | static int bsr_mmap(struct file *filp, struct vm_area_struct *vma) |
121 | { | 125 | { |
@@ -308,7 +312,7 @@ static int __init bsr_init(void) | |||
308 | ret = PTR_ERR(bsr_class); | 312 | ret = PTR_ERR(bsr_class); |
309 | goto out_err_1; | 313 | goto out_err_1; |
310 | } | 314 | } |
311 | bsr_class->dev_attrs = bsr_dev_attrs; | 315 | bsr_class->dev_groups = bsr_dev_groups; |
312 | 316 | ||
313 | ret = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr"); | 317 | ret = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr"); |
314 | bsr_major = MAJOR(bsr_dev); | 318 | bsr_major = MAJOR(bsr_dev); |
diff --git a/drivers/char/tile-srom.c b/drivers/char/tile-srom.c index 7faeb1cde97d..ae82933883bd 100644 --- a/drivers/char/tile-srom.c +++ b/drivers/char/tile-srom.c | |||
@@ -279,33 +279,37 @@ loff_t srom_llseek(struct file *file, loff_t offset, int origin) | |||
279 | return fixed_size_llseek(file, offset, origin, srom->total_size); | 279 | return fixed_size_llseek(file, offset, origin, srom->total_size); |
280 | } | 280 | } |
281 | 281 | ||
282 | static ssize_t total_show(struct device *dev, | 282 | static ssize_t total_size_show(struct device *dev, |
283 | struct device_attribute *attr, char *buf) | 283 | struct device_attribute *attr, char *buf) |
284 | { | 284 | { |
285 | struct srom_dev *srom = dev_get_drvdata(dev); | 285 | struct srom_dev *srom = dev_get_drvdata(dev); |
286 | return sprintf(buf, "%u\n", srom->total_size); | 286 | return sprintf(buf, "%u\n", srom->total_size); |
287 | } | 287 | } |
288 | static DEVICE_ATTR_RO(total_size); | ||
288 | 289 | ||
289 | static ssize_t sector_show(struct device *dev, | 290 | static ssize_t sector_size_show(struct device *dev, |
290 | struct device_attribute *attr, char *buf) | 291 | struct device_attribute *attr, char *buf) |
291 | { | 292 | { |
292 | struct srom_dev *srom = dev_get_drvdata(dev); | 293 | struct srom_dev *srom = dev_get_drvdata(dev); |
293 | return sprintf(buf, "%u\n", srom->sector_size); | 294 | return sprintf(buf, "%u\n", srom->sector_size); |
294 | } | 295 | } |
296 | static DEVICE_ATTR_RO(sector_size); | ||
295 | 297 | ||
296 | static ssize_t page_show(struct device *dev, | 298 | static ssize_t page_size_show(struct device *dev, |
297 | struct device_attribute *attr, char *buf) | 299 | struct device_attribute *attr, char *buf) |
298 | { | 300 | { |
299 | struct srom_dev *srom = dev_get_drvdata(dev); | 301 | struct srom_dev *srom = dev_get_drvdata(dev); |
300 | return sprintf(buf, "%u\n", srom->page_size); | 302 | return sprintf(buf, "%u\n", srom->page_size); |
301 | } | 303 | } |
304 | static DEVICE_ATTR_RO(page_size); | ||
302 | 305 | ||
303 | static struct device_attribute srom_dev_attrs[] = { | 306 | static struct attribute *srom_dev_attrs[] = { |
304 | __ATTR(total_size, S_IRUGO, total_show, NULL), | 307 | &dev_attr_total_size.attr, |
305 | __ATTR(sector_size, S_IRUGO, sector_show, NULL), | 308 | &dev_attr_sector_size.attr, |
306 | __ATTR(page_size, S_IRUGO, page_show, NULL), | 309 | &dev_attr_page_size.attr, |
307 | __ATTR_NULL | 310 | NULL, |
308 | }; | 311 | }; |
312 | ATTRIBUTE_GROUPS(srom_dev); | ||
309 | 313 | ||
310 | static char *srom_devnode(struct device *dev, umode_t *mode) | 314 | static char *srom_devnode(struct device *dev, umode_t *mode) |
311 | { | 315 | { |
@@ -418,7 +422,7 @@ static int srom_init(void) | |||
418 | result = PTR_ERR(srom_class); | 422 | result = PTR_ERR(srom_class); |
419 | goto fail_cdev; | 423 | goto fail_cdev; |
420 | } | 424 | } |
421 | srom_class->dev_attrs = srom_dev_attrs; | 425 | srom_class->dev_groups = srom_dev_groups; |
422 | srom_class->devnode = srom_devnode; | 426 | srom_class->devnode = srom_devnode; |
423 | 427 | ||
424 | /* Do per-partition initialization */ | 428 | /* Do per-partition initialization */ |
diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index e94e619fe050..c99c00d35d34 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c | |||
@@ -703,7 +703,7 @@ err_out: | |||
703 | } | 703 | } |
704 | EXPORT_SYMBOL(devfreq_remove_governor); | 704 | EXPORT_SYMBOL(devfreq_remove_governor); |
705 | 705 | ||
706 | static ssize_t show_governor(struct device *dev, | 706 | static ssize_t governor_show(struct device *dev, |
707 | struct device_attribute *attr, char *buf) | 707 | struct device_attribute *attr, char *buf) |
708 | { | 708 | { |
709 | if (!to_devfreq(dev)->governor) | 709 | if (!to_devfreq(dev)->governor) |
@@ -712,7 +712,7 @@ static ssize_t show_governor(struct device *dev, | |||
712 | return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name); | 712 | return sprintf(buf, "%s\n", to_devfreq(dev)->governor->name); |
713 | } | 713 | } |
714 | 714 | ||
715 | static ssize_t store_governor(struct device *dev, struct device_attribute *attr, | 715 | static ssize_t governor_store(struct device *dev, struct device_attribute *attr, |
716 | const char *buf, size_t count) | 716 | const char *buf, size_t count) |
717 | { | 717 | { |
718 | struct devfreq *df = to_devfreq(dev); | 718 | struct devfreq *df = to_devfreq(dev); |
@@ -754,9 +754,11 @@ out: | |||
754 | ret = count; | 754 | ret = count; |
755 | return ret; | 755 | return ret; |
756 | } | 756 | } |
757 | static ssize_t show_available_governors(struct device *d, | 757 | static DEVICE_ATTR_RW(governor); |
758 | struct device_attribute *attr, | 758 | |
759 | char *buf) | 759 | static ssize_t available_governors_show(struct device *d, |
760 | struct device_attribute *attr, | ||
761 | char *buf) | ||
760 | { | 762 | { |
761 | struct devfreq_governor *tmp_governor; | 763 | struct devfreq_governor *tmp_governor; |
762 | ssize_t count = 0; | 764 | ssize_t count = 0; |
@@ -775,9 +777,10 @@ static ssize_t show_available_governors(struct device *d, | |||
775 | 777 | ||
776 | return count; | 778 | return count; |
777 | } | 779 | } |
780 | static DEVICE_ATTR_RO(available_governors); | ||
778 | 781 | ||
779 | static ssize_t show_freq(struct device *dev, | 782 | static ssize_t cur_freq_show(struct device *dev, struct device_attribute *attr, |
780 | struct device_attribute *attr, char *buf) | 783 | char *buf) |
781 | { | 784 | { |
782 | unsigned long freq; | 785 | unsigned long freq; |
783 | struct devfreq *devfreq = to_devfreq(dev); | 786 | struct devfreq *devfreq = to_devfreq(dev); |
@@ -788,20 +791,22 @@ static ssize_t show_freq(struct device *dev, | |||
788 | 791 | ||
789 | return sprintf(buf, "%lu\n", devfreq->previous_freq); | 792 | return sprintf(buf, "%lu\n", devfreq->previous_freq); |
790 | } | 793 | } |
794 | static DEVICE_ATTR_RO(cur_freq); | ||
791 | 795 | ||
792 | static ssize_t show_target_freq(struct device *dev, | 796 | static ssize_t target_freq_show(struct device *dev, |
793 | struct device_attribute *attr, char *buf) | 797 | struct device_attribute *attr, char *buf) |
794 | { | 798 | { |
795 | return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); | 799 | return sprintf(buf, "%lu\n", to_devfreq(dev)->previous_freq); |
796 | } | 800 | } |
801 | static DEVICE_ATTR_RO(target_freq); | ||
797 | 802 | ||
798 | static ssize_t show_polling_interval(struct device *dev, | 803 | static ssize_t polling_interval_show(struct device *dev, |
799 | struct device_attribute *attr, char *buf) | 804 | struct device_attribute *attr, char *buf) |
800 | { | 805 | { |
801 | return sprintf(buf, "%d\n", to_devfreq(dev)->profile->polling_ms); | 806 | return sprintf(buf, "%d\n", to_devfreq(dev)->profile->polling_ms); |
802 | } | 807 | } |
803 | 808 | ||
804 | static ssize_t store_polling_interval(struct device *dev, | 809 | static ssize_t polling_interval_store(struct device *dev, |
805 | struct device_attribute *attr, | 810 | struct device_attribute *attr, |
806 | const char *buf, size_t count) | 811 | const char *buf, size_t count) |
807 | { | 812 | { |
@@ -821,8 +826,9 @@ static ssize_t store_polling_interval(struct device *dev, | |||
821 | 826 | ||
822 | return ret; | 827 | return ret; |
823 | } | 828 | } |
829 | static DEVICE_ATTR_RW(polling_interval); | ||
824 | 830 | ||
825 | static ssize_t store_min_freq(struct device *dev, struct device_attribute *attr, | 831 | static ssize_t min_freq_store(struct device *dev, struct device_attribute *attr, |
826 | const char *buf, size_t count) | 832 | const char *buf, size_t count) |
827 | { | 833 | { |
828 | struct devfreq *df = to_devfreq(dev); | 834 | struct devfreq *df = to_devfreq(dev); |
@@ -849,13 +855,13 @@ unlock: | |||
849 | return ret; | 855 | return ret; |
850 | } | 856 | } |
851 | 857 | ||
852 | static ssize_t show_min_freq(struct device *dev, struct device_attribute *attr, | 858 | static ssize_t min_freq_show(struct device *dev, struct device_attribute *attr, |
853 | char *buf) | 859 | char *buf) |
854 | { | 860 | { |
855 | return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq); | 861 | return sprintf(buf, "%lu\n", to_devfreq(dev)->min_freq); |
856 | } | 862 | } |
857 | 863 | ||
858 | static ssize_t store_max_freq(struct device *dev, struct device_attribute *attr, | 864 | static ssize_t max_freq_store(struct device *dev, struct device_attribute *attr, |
859 | const char *buf, size_t count) | 865 | const char *buf, size_t count) |
860 | { | 866 | { |
861 | struct devfreq *df = to_devfreq(dev); | 867 | struct devfreq *df = to_devfreq(dev); |
@@ -881,16 +887,18 @@ unlock: | |||
881 | mutex_unlock(&df->lock); | 887 | mutex_unlock(&df->lock); |
882 | return ret; | 888 | return ret; |
883 | } | 889 | } |
890 | static DEVICE_ATTR_RW(min_freq); | ||
884 | 891 | ||
885 | static ssize_t show_max_freq(struct device *dev, struct device_attribute *attr, | 892 | static ssize_t max_freq_show(struct device *dev, struct device_attribute *attr, |
886 | char *buf) | 893 | char *buf) |
887 | { | 894 | { |
888 | return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq); | 895 | return sprintf(buf, "%lu\n", to_devfreq(dev)->max_freq); |
889 | } | 896 | } |
897 | static DEVICE_ATTR_RW(max_freq); | ||
890 | 898 | ||
891 | static ssize_t show_available_freqs(struct device *d, | 899 | static ssize_t available_frequencies_show(struct device *d, |
892 | struct device_attribute *attr, | 900 | struct device_attribute *attr, |
893 | char *buf) | 901 | char *buf) |
894 | { | 902 | { |
895 | struct devfreq *df = to_devfreq(d); | 903 | struct devfreq *df = to_devfreq(d); |
896 | struct device *dev = df->dev.parent; | 904 | struct device *dev = df->dev.parent; |
@@ -918,9 +926,10 @@ static ssize_t show_available_freqs(struct device *d, | |||
918 | 926 | ||
919 | return count; | 927 | return count; |
920 | } | 928 | } |
929 | static DEVICE_ATTR_RO(available_frequencies); | ||
921 | 930 | ||
922 | static ssize_t show_trans_table(struct device *dev, struct device_attribute *attr, | 931 | static ssize_t trans_stat_show(struct device *dev, |
923 | char *buf) | 932 | struct device_attribute *attr, char *buf) |
924 | { | 933 | { |
925 | struct devfreq *devfreq = to_devfreq(dev); | 934 | struct devfreq *devfreq = to_devfreq(dev); |
926 | ssize_t len; | 935 | ssize_t len; |
@@ -959,20 +968,21 @@ static ssize_t show_trans_table(struct device *dev, struct device_attribute *att | |||
959 | devfreq->total_trans); | 968 | devfreq->total_trans); |
960 | return len; | 969 | return len; |
961 | } | 970 | } |
962 | 971 | static DEVICE_ATTR_RO(trans_stat); | |
963 | static struct device_attribute devfreq_attrs[] = { | 972 | |
964 | __ATTR(governor, S_IRUGO | S_IWUSR, show_governor, store_governor), | 973 | static struct attribute *devfreq_attrs[] = { |
965 | __ATTR(available_governors, S_IRUGO, show_available_governors, NULL), | 974 | &dev_attr_governor.attr, |
966 | __ATTR(cur_freq, S_IRUGO, show_freq, NULL), | 975 | &dev_attr_available_governors.attr, |
967 | __ATTR(available_frequencies, S_IRUGO, show_available_freqs, NULL), | 976 | &dev_attr_cur_freq.attr, |
968 | __ATTR(target_freq, S_IRUGO, show_target_freq, NULL), | 977 | &dev_attr_available_frequencies.attr, |
969 | __ATTR(polling_interval, S_IRUGO | S_IWUSR, show_polling_interval, | 978 | &dev_attr_target_freq.attr, |
970 | store_polling_interval), | 979 | &dev_attr_polling_interval.attr, |
971 | __ATTR(min_freq, S_IRUGO | S_IWUSR, show_min_freq, store_min_freq), | 980 | &dev_attr_min_freq.attr, |
972 | __ATTR(max_freq, S_IRUGO | S_IWUSR, show_max_freq, store_max_freq), | 981 | &dev_attr_max_freq.attr, |
973 | __ATTR(trans_stat, S_IRUGO, show_trans_table, NULL), | 982 | &dev_attr_trans_stat.attr, |
974 | { }, | 983 | NULL, |
975 | }; | 984 | }; |
985 | ATTRIBUTE_GROUPS(devfreq); | ||
976 | 986 | ||
977 | static int __init devfreq_init(void) | 987 | static int __init devfreq_init(void) |
978 | { | 988 | { |
@@ -988,7 +998,7 @@ static int __init devfreq_init(void) | |||
988 | pr_err("%s: couldn't create workqueue\n", __FILE__); | 998 | pr_err("%s: couldn't create workqueue\n", __FILE__); |
989 | return PTR_ERR(devfreq_wq); | 999 | return PTR_ERR(devfreq_wq); |
990 | } | 1000 | } |
991 | devfreq_class->dev_attrs = devfreq_attrs; | 1001 | devfreq_class->dev_groups = devfreq_groups; |
992 | 1002 | ||
993 | return 0; | 1003 | return 0; |
994 | } | 1004 | } |
diff --git a/drivers/dma/dmaengine.c b/drivers/dma/dmaengine.c index 9e56745f87bf..99af4db5948b 100644 --- a/drivers/dma/dmaengine.c +++ b/drivers/dma/dmaengine.c | |||
@@ -87,7 +87,8 @@ static struct dma_chan *dev_to_dma_chan(struct device *dev) | |||
87 | return chan_dev->chan; | 87 | return chan_dev->chan; |
88 | } | 88 | } |
89 | 89 | ||
90 | static ssize_t show_memcpy_count(struct device *dev, struct device_attribute *attr, char *buf) | 90 | static ssize_t memcpy_count_show(struct device *dev, |
91 | struct device_attribute *attr, char *buf) | ||
91 | { | 92 | { |
92 | struct dma_chan *chan; | 93 | struct dma_chan *chan; |
93 | unsigned long count = 0; | 94 | unsigned long count = 0; |
@@ -106,9 +107,10 @@ static ssize_t show_memcpy_count(struct device *dev, struct device_attribute *at | |||
106 | 107 | ||
107 | return err; | 108 | return err; |
108 | } | 109 | } |
110 | static DEVICE_ATTR_RO(memcpy_count); | ||
109 | 111 | ||
110 | static ssize_t show_bytes_transferred(struct device *dev, struct device_attribute *attr, | 112 | static ssize_t bytes_transferred_show(struct device *dev, |
111 | char *buf) | 113 | struct device_attribute *attr, char *buf) |
112 | { | 114 | { |
113 | struct dma_chan *chan; | 115 | struct dma_chan *chan; |
114 | unsigned long count = 0; | 116 | unsigned long count = 0; |
@@ -127,8 +129,10 @@ static ssize_t show_bytes_transferred(struct device *dev, struct device_attribut | |||
127 | 129 | ||
128 | return err; | 130 | return err; |
129 | } | 131 | } |
132 | static DEVICE_ATTR_RO(bytes_transferred); | ||
130 | 133 | ||
131 | static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, char *buf) | 134 | static ssize_t in_use_show(struct device *dev, struct device_attribute *attr, |
135 | char *buf) | ||
132 | { | 136 | { |
133 | struct dma_chan *chan; | 137 | struct dma_chan *chan; |
134 | int err; | 138 | int err; |
@@ -143,13 +147,15 @@ static ssize_t show_in_use(struct device *dev, struct device_attribute *attr, ch | |||
143 | 147 | ||
144 | return err; | 148 | return err; |
145 | } | 149 | } |
150 | static DEVICE_ATTR_RO(in_use); | ||
146 | 151 | ||
147 | static struct device_attribute dma_attrs[] = { | 152 | static struct attribute *dma_dev_attrs[] = { |
148 | __ATTR(memcpy_count, S_IRUGO, show_memcpy_count, NULL), | 153 | &dev_attr_memcpy_count.attr, |
149 | __ATTR(bytes_transferred, S_IRUGO, show_bytes_transferred, NULL), | 154 | &dev_attr_bytes_transferred.attr, |
150 | __ATTR(in_use, S_IRUGO, show_in_use, NULL), | 155 | &dev_attr_in_use.attr, |
151 | __ATTR_NULL | 156 | NULL, |
152 | }; | 157 | }; |
158 | ATTRIBUTE_GROUPS(dma_dev); | ||
153 | 159 | ||
154 | static void chan_dev_release(struct device *dev) | 160 | static void chan_dev_release(struct device *dev) |
155 | { | 161 | { |
@@ -167,7 +173,7 @@ static void chan_dev_release(struct device *dev) | |||
167 | 173 | ||
168 | static struct class dma_devclass = { | 174 | static struct class dma_devclass = { |
169 | .name = "dma", | 175 | .name = "dma", |
170 | .dev_attrs = dma_attrs, | 176 | .dev_groups = dma_dev_groups, |
171 | .dev_release = chan_dev_release, | 177 | .dev_release = chan_dev_release, |
172 | }; | 178 | }; |
173 | 179 | ||
diff --git a/drivers/extcon/extcon-class.c b/drivers/extcon/extcon-class.c index 1446152bf2e9..148382faded9 100644 --- a/drivers/extcon/extcon-class.c +++ b/drivers/extcon/extcon-class.c | |||
@@ -148,6 +148,7 @@ static ssize_t state_store(struct device *dev, struct device_attribute *attr, | |||
148 | 148 | ||
149 | return count; | 149 | return count; |
150 | } | 150 | } |
151 | static DEVICE_ATTR_RW(state); | ||
151 | 152 | ||
152 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, | 153 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, |
153 | char *buf) | 154 | char *buf) |
@@ -163,6 +164,7 @@ static ssize_t name_show(struct device *dev, struct device_attribute *attr, | |||
163 | 164 | ||
164 | return sprintf(buf, "%s\n", dev_name(edev->dev)); | 165 | return sprintf(buf, "%s\n", dev_name(edev->dev)); |
165 | } | 166 | } |
167 | static DEVICE_ATTR_RO(name); | ||
166 | 168 | ||
167 | static ssize_t cable_name_show(struct device *dev, | 169 | static ssize_t cable_name_show(struct device *dev, |
168 | struct device_attribute *attr, char *buf) | 170 | struct device_attribute *attr, char *buf) |
@@ -527,11 +529,12 @@ int extcon_unregister_notifier(struct extcon_dev *edev, | |||
527 | } | 529 | } |
528 | EXPORT_SYMBOL_GPL(extcon_unregister_notifier); | 530 | EXPORT_SYMBOL_GPL(extcon_unregister_notifier); |
529 | 531 | ||
530 | static struct device_attribute extcon_attrs[] = { | 532 | static struct attribute *extcon_attrs[] = { |
531 | __ATTR(state, S_IRUGO | S_IWUSR, state_show, state_store), | 533 | &dev_attr_state.attr, |
532 | __ATTR_RO(name), | 534 | &dev_attr_name.attr, |
533 | __ATTR_NULL, | 535 | NULL, |
534 | }; | 536 | }; |
537 | ATTRIBUTE_GROUPS(extcon); | ||
535 | 538 | ||
536 | static int create_extcon_class(void) | 539 | static int create_extcon_class(void) |
537 | { | 540 | { |
@@ -539,7 +542,7 @@ static int create_extcon_class(void) | |||
539 | extcon_class = class_create(THIS_MODULE, "extcon"); | 542 | extcon_class = class_create(THIS_MODULE, "extcon"); |
540 | if (IS_ERR(extcon_class)) | 543 | if (IS_ERR(extcon_class)) |
541 | return PTR_ERR(extcon_class); | 544 | return PTR_ERR(extcon_class); |
542 | extcon_class->dev_attrs = extcon_attrs; | 545 | extcon_class->dev_groups = extcon_groups; |
543 | 546 | ||
544 | #if defined(CONFIG_ANDROID) | 547 | #if defined(CONFIG_ANDROID) |
545 | switch_class = class_compat_register("switch"); | 548 | switch_class = class_compat_register("switch"); |
diff --git a/drivers/firmware/dcdbas.c b/drivers/firmware/dcdbas.c index 8e77c02edb24..ff080ee20197 100644 --- a/drivers/firmware/dcdbas.c +++ b/drivers/firmware/dcdbas.c | |||
@@ -535,11 +535,12 @@ static struct attribute *dcdbas_dev_attrs[] = { | |||
535 | 535 | ||
536 | static struct attribute_group dcdbas_attr_group = { | 536 | static struct attribute_group dcdbas_attr_group = { |
537 | .attrs = dcdbas_dev_attrs, | 537 | .attrs = dcdbas_dev_attrs, |
538 | .bin_attrs = dcdbas_bin_attrs, | ||
538 | }; | 539 | }; |
539 | 540 | ||
540 | static int dcdbas_probe(struct platform_device *dev) | 541 | static int dcdbas_probe(struct platform_device *dev) |
541 | { | 542 | { |
542 | int i, error; | 543 | int error; |
543 | 544 | ||
544 | host_control_action = HC_ACTION_NONE; | 545 | host_control_action = HC_ACTION_NONE; |
545 | host_control_smi_type = HC_SMITYPE_NONE; | 546 | host_control_smi_type = HC_SMITYPE_NONE; |
@@ -555,18 +556,6 @@ static int dcdbas_probe(struct platform_device *dev) | |||
555 | if (error) | 556 | if (error) |
556 | return error; | 557 | return error; |
557 | 558 | ||
558 | for (i = 0; dcdbas_bin_attrs[i]; i++) { | ||
559 | error = sysfs_create_bin_file(&dev->dev.kobj, | ||
560 | dcdbas_bin_attrs[i]); | ||
561 | if (error) { | ||
562 | while (--i >= 0) | ||
563 | sysfs_remove_bin_file(&dev->dev.kobj, | ||
564 | dcdbas_bin_attrs[i]); | ||
565 | sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group); | ||
566 | return error; | ||
567 | } | ||
568 | } | ||
569 | |||
570 | register_reboot_notifier(&dcdbas_reboot_nb); | 559 | register_reboot_notifier(&dcdbas_reboot_nb); |
571 | 560 | ||
572 | dev_info(&dev->dev, "%s (version %s)\n", | 561 | dev_info(&dev->dev, "%s (version %s)\n", |
@@ -577,11 +566,7 @@ static int dcdbas_probe(struct platform_device *dev) | |||
577 | 566 | ||
578 | static int dcdbas_remove(struct platform_device *dev) | 567 | static int dcdbas_remove(struct platform_device *dev) |
579 | { | 568 | { |
580 | int i; | ||
581 | |||
582 | unregister_reboot_notifier(&dcdbas_reboot_nb); | 569 | unregister_reboot_notifier(&dcdbas_reboot_nb); |
583 | for (i = 0; dcdbas_bin_attrs[i]; i++) | ||
584 | sysfs_remove_bin_file(&dev->dev.kobj, dcdbas_bin_attrs[i]); | ||
585 | sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group); | 570 | sysfs_remove_group(&dev->dev.kobj, &dcdbas_attr_group); |
586 | 571 | ||
587 | return 0; | 572 | return 0; |
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c index 36668d1aca8f..b8f1c77f2f77 100644 --- a/drivers/hid/hid-core.c +++ b/drivers/hid/hid-core.c | |||
@@ -1917,11 +1917,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | |||
1917 | 1917 | ||
1918 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 1918 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
1919 | } | 1919 | } |
1920 | static DEVICE_ATTR_RO(modalias); | ||
1920 | 1921 | ||
1921 | static struct device_attribute hid_dev_attrs[] = { | 1922 | static struct attribute *hid_dev_attrs[] = { |
1922 | __ATTR_RO(modalias), | 1923 | &dev_attr_modalias.attr, |
1923 | __ATTR_NULL, | 1924 | NULL, |
1924 | }; | 1925 | }; |
1926 | ATTRIBUTE_GROUPS(hid_dev); | ||
1925 | 1927 | ||
1926 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) | 1928 | static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) |
1927 | { | 1929 | { |
@@ -1949,7 +1951,7 @@ static int hid_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
1949 | 1951 | ||
1950 | static struct bus_type hid_bus_type = { | 1952 | static struct bus_type hid_bus_type = { |
1951 | .name = "hid", | 1953 | .name = "hid", |
1952 | .dev_attrs = hid_dev_attrs, | 1954 | .dev_groups = hid_dev_groups, |
1953 | .match = hid_bus_match, | 1955 | .match = hid_bus_match, |
1954 | .probe = hid_device_probe, | 1956 | .probe = hid_device_probe, |
1955 | .remove = hid_device_remove, | 1957 | .remove = hid_device_remove, |
diff --git a/drivers/hid/hid-roccat-arvo.c b/drivers/hid/hid-roccat-arvo.c index 327f9b8ed1f4..eed7f52084c5 100644 --- a/drivers/hid/hid-roccat-arvo.c +++ b/drivers/hid/hid-roccat-arvo.c | |||
@@ -75,6 +75,8 @@ static ssize_t arvo_sysfs_set_mode_key(struct device *dev, | |||
75 | 75 | ||
76 | return size; | 76 | return size; |
77 | } | 77 | } |
78 | static DEVICE_ATTR(mode_key, 0660, | ||
79 | arvo_sysfs_show_mode_key, arvo_sysfs_set_mode_key); | ||
78 | 80 | ||
79 | static ssize_t arvo_sysfs_show_key_mask(struct device *dev, | 81 | static ssize_t arvo_sysfs_show_key_mask(struct device *dev, |
80 | struct device_attribute *attr, char *buf) | 82 | struct device_attribute *attr, char *buf) |
@@ -123,6 +125,8 @@ static ssize_t arvo_sysfs_set_key_mask(struct device *dev, | |||
123 | 125 | ||
124 | return size; | 126 | return size; |
125 | } | 127 | } |
128 | static DEVICE_ATTR(key_mask, 0660, | ||
129 | arvo_sysfs_show_key_mask, arvo_sysfs_set_key_mask); | ||
126 | 130 | ||
127 | /* retval is 1-5 on success, < 0 on error */ | 131 | /* retval is 1-5 on success, < 0 on error */ |
128 | static int arvo_get_actual_profile(struct usb_device *usb_dev) | 132 | 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, | |||
179 | mutex_unlock(&arvo->arvo_lock); | 183 | mutex_unlock(&arvo->arvo_lock); |
180 | return retval; | 184 | return retval; |
181 | } | 185 | } |
186 | static DEVICE_ATTR(actual_profile, 0660, | ||
187 | arvo_sysfs_show_actual_profile, | ||
188 | arvo_sysfs_set_actual_profile); | ||
182 | 189 | ||
183 | static ssize_t arvo_sysfs_write(struct file *fp, | 190 | static ssize_t arvo_sysfs_write(struct file *fp, |
184 | struct kobject *kobj, void const *buf, | 191 | struct kobject *kobj, void const *buf, |
@@ -230,6 +237,8 @@ static ssize_t arvo_sysfs_write_button(struct file *fp, | |||
230 | return arvo_sysfs_write(fp, kobj, buf, off, count, | 237 | return arvo_sysfs_write(fp, kobj, buf, off, count, |
231 | sizeof(struct arvo_button), ARVO_COMMAND_BUTTON); | 238 | sizeof(struct arvo_button), ARVO_COMMAND_BUTTON); |
232 | } | 239 | } |
240 | static BIN_ATTR(button, 0220, NULL, arvo_sysfs_write_button, | ||
241 | sizeof(struct arvo_button)); | ||
233 | 242 | ||
234 | static ssize_t arvo_sysfs_read_info(struct file *fp, | 243 | static ssize_t arvo_sysfs_read_info(struct file *fp, |
235 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 244 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
@@ -238,31 +247,30 @@ static ssize_t arvo_sysfs_read_info(struct file *fp, | |||
238 | return arvo_sysfs_read(fp, kobj, buf, off, count, | 247 | return arvo_sysfs_read(fp, kobj, buf, off, count, |
239 | sizeof(struct arvo_info), ARVO_COMMAND_INFO); | 248 | sizeof(struct arvo_info), ARVO_COMMAND_INFO); |
240 | } | 249 | } |
250 | static BIN_ATTR(info, 0440, arvo_sysfs_read_info, NULL, | ||
251 | sizeof(struct arvo_info)); | ||
252 | |||
253 | static struct attribute *arvo_attrs[] = { | ||
254 | &dev_attr_mode_key.attr, | ||
255 | &dev_attr_key_mask.attr, | ||
256 | &dev_attr_actual_profile.attr, | ||
257 | NULL, | ||
258 | }; | ||
241 | 259 | ||
260 | static struct bin_attribute *arvo_bin_attributes[] = { | ||
261 | &bin_attr_button, | ||
262 | &bin_attr_info, | ||
263 | NULL, | ||
264 | }; | ||
242 | 265 | ||
243 | static struct device_attribute arvo_attributes[] = { | 266 | static const struct attribute_group arvo_group = { |
244 | __ATTR(mode_key, 0660, | 267 | .attrs = arvo_attrs, |
245 | arvo_sysfs_show_mode_key, arvo_sysfs_set_mode_key), | 268 | .bin_attrs = arvo_bin_attributes, |
246 | __ATTR(key_mask, 0660, | ||
247 | arvo_sysfs_show_key_mask, arvo_sysfs_set_key_mask), | ||
248 | __ATTR(actual_profile, 0660, | ||
249 | arvo_sysfs_show_actual_profile, | ||
250 | arvo_sysfs_set_actual_profile), | ||
251 | __ATTR_NULL | ||
252 | }; | 269 | }; |
253 | 270 | ||
254 | static struct bin_attribute arvo_bin_attributes[] = { | 271 | static const struct attribute_group *arvo_groups[] = { |
255 | { | 272 | &arvo_group, |
256 | .attr = { .name = "button", .mode = 0220 }, | 273 | NULL, |
257 | .size = sizeof(struct arvo_button), | ||
258 | .write = arvo_sysfs_write_button | ||
259 | }, | ||
260 | { | ||
261 | .attr = { .name = "info", .mode = 0440 }, | ||
262 | .size = sizeof(struct arvo_info), | ||
263 | .read = arvo_sysfs_read_info | ||
264 | }, | ||
265 | __ATTR_NULL | ||
266 | }; | 274 | }; |
267 | 275 | ||
268 | static int arvo_init_arvo_device_struct(struct usb_device *usb_dev, | 276 | static int arvo_init_arvo_device_struct(struct usb_device *usb_dev, |
@@ -430,8 +438,7 @@ static int __init arvo_init(void) | |||
430 | arvo_class = class_create(THIS_MODULE, "arvo"); | 438 | arvo_class = class_create(THIS_MODULE, "arvo"); |
431 | if (IS_ERR(arvo_class)) | 439 | if (IS_ERR(arvo_class)) |
432 | return PTR_ERR(arvo_class); | 440 | return PTR_ERR(arvo_class); |
433 | arvo_class->dev_attrs = arvo_attributes; | 441 | arvo_class->dev_groups = arvo_groups; |
434 | arvo_class->dev_bin_attrs = arvo_bin_attributes; | ||
435 | 442 | ||
436 | retval = hid_register_driver(&arvo_driver); | 443 | retval = hid_register_driver(&arvo_driver); |
437 | if (retval) | 444 | if (retval) |
diff --git a/drivers/hid/hid-roccat-isku.c b/drivers/hid/hid-roccat-isku.c index 8023751d5257..b7a4e10e112e 100644 --- a/drivers/hid/hid-roccat-isku.c +++ b/drivers/hid/hid-roccat-isku.c | |||
@@ -109,12 +109,12 @@ static ssize_t isku_sysfs_set_actual_profile(struct device *dev, | |||
109 | 109 | ||
110 | return size; | 110 | return size; |
111 | } | 111 | } |
112 | static DEVICE_ATTR(actual_profile, 0660, isku_sysfs_show_actual_profile, | ||
113 | isku_sysfs_set_actual_profile); | ||
112 | 114 | ||
113 | static struct device_attribute isku_attributes[] = { | 115 | static struct attribute *isku_attrs[] = { |
114 | __ATTR(actual_profile, 0660, | 116 | &dev_attr_actual_profile.attr, |
115 | isku_sysfs_show_actual_profile, | 117 | NULL, |
116 | isku_sysfs_set_actual_profile), | ||
117 | __ATTR_NULL | ||
118 | }; | 118 | }; |
119 | 119 | ||
120 | static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj, | 120 | static ssize_t isku_sysfs_read(struct file *fp, struct kobject *kobj, |
@@ -184,7 +184,8 @@ ISKU_SYSFS_R(thingy, THINGY) \ | |||
184 | ISKU_SYSFS_W(thingy, THINGY) | 184 | ISKU_SYSFS_W(thingy, THINGY) |
185 | 185 | ||
186 | #define ISKU_BIN_ATTR_RW(thingy, THINGY) \ | 186 | #define ISKU_BIN_ATTR_RW(thingy, THINGY) \ |
187 | { \ | 187 | ISKU_SYSFS_RW(thingy, THINGY); \ |
188 | static struct bin_attribute bin_attr_##thingy = { \ | ||
188 | .attr = { .name = #thingy, .mode = 0660 }, \ | 189 | .attr = { .name = #thingy, .mode = 0660 }, \ |
189 | .size = ISKU_SIZE_ ## THINGY, \ | 190 | .size = ISKU_SIZE_ ## THINGY, \ |
190 | .read = isku_sysfs_read_ ## thingy, \ | 191 | .read = isku_sysfs_read_ ## thingy, \ |
@@ -192,52 +193,64 @@ ISKU_SYSFS_W(thingy, THINGY) | |||
192 | } | 193 | } |
193 | 194 | ||
194 | #define ISKU_BIN_ATTR_R(thingy, THINGY) \ | 195 | #define ISKU_BIN_ATTR_R(thingy, THINGY) \ |
195 | { \ | 196 | ISKU_SYSFS_R(thingy, THINGY); \ |
197 | static struct bin_attribute bin_attr_##thingy = { \ | ||
196 | .attr = { .name = #thingy, .mode = 0440 }, \ | 198 | .attr = { .name = #thingy, .mode = 0440 }, \ |
197 | .size = ISKU_SIZE_ ## THINGY, \ | 199 | .size = ISKU_SIZE_ ## THINGY, \ |
198 | .read = isku_sysfs_read_ ## thingy, \ | 200 | .read = isku_sysfs_read_ ## thingy, \ |
199 | } | 201 | } |
200 | 202 | ||
201 | #define ISKU_BIN_ATTR_W(thingy, THINGY) \ | 203 | #define ISKU_BIN_ATTR_W(thingy, THINGY) \ |
202 | { \ | 204 | ISKU_SYSFS_W(thingy, THINGY); \ |
205 | static struct bin_attribute bin_attr_##thingy = { \ | ||
203 | .attr = { .name = #thingy, .mode = 0220 }, \ | 206 | .attr = { .name = #thingy, .mode = 0220 }, \ |
204 | .size = ISKU_SIZE_ ## THINGY, \ | 207 | .size = ISKU_SIZE_ ## THINGY, \ |
205 | .write = isku_sysfs_write_ ## thingy \ | 208 | .write = isku_sysfs_write_ ## thingy \ |
206 | } | 209 | } |
207 | 210 | ||
208 | ISKU_SYSFS_RW(macro, MACRO) | 211 | ISKU_BIN_ATTR_RW(macro, MACRO); |
209 | ISKU_SYSFS_RW(keys_function, KEYS_FUNCTION) | 212 | ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION); |
210 | ISKU_SYSFS_RW(keys_easyzone, KEYS_EASYZONE) | 213 | ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE); |
211 | ISKU_SYSFS_RW(keys_media, KEYS_MEDIA) | 214 | ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA); |
212 | ISKU_SYSFS_RW(keys_thumbster, KEYS_THUMBSTER) | 215 | ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER); |
213 | ISKU_SYSFS_RW(keys_macro, KEYS_MACRO) | 216 | ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO); |
214 | ISKU_SYSFS_RW(keys_capslock, KEYS_CAPSLOCK) | 217 | ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK); |
215 | ISKU_SYSFS_RW(light, LIGHT) | 218 | ISKU_BIN_ATTR_RW(light, LIGHT); |
216 | ISKU_SYSFS_RW(key_mask, KEY_MASK) | 219 | ISKU_BIN_ATTR_RW(key_mask, KEY_MASK); |
217 | ISKU_SYSFS_RW(last_set, LAST_SET) | 220 | ISKU_BIN_ATTR_RW(last_set, LAST_SET); |
218 | ISKU_SYSFS_W(talk, TALK) | 221 | ISKU_BIN_ATTR_W(talk, TALK); |
219 | ISKU_SYSFS_W(talkfx, TALKFX) | 222 | ISKU_BIN_ATTR_W(talkfx, TALKFX); |
220 | ISKU_SYSFS_R(info, INFO) | 223 | ISKU_BIN_ATTR_W(control, CONTROL); |
221 | ISKU_SYSFS_W(control, CONTROL) | 224 | ISKU_BIN_ATTR_W(reset, RESET); |
222 | ISKU_SYSFS_W(reset, RESET) | 225 | ISKU_BIN_ATTR_R(info, INFO); |
223 | 226 | ||
224 | static struct bin_attribute isku_bin_attributes[] = { | 227 | static struct bin_attribute *isku_bin_attributes[] = { |
225 | ISKU_BIN_ATTR_RW(macro, MACRO), | 228 | &bin_attr_macro, |
226 | ISKU_BIN_ATTR_RW(keys_function, KEYS_FUNCTION), | 229 | &bin_attr_keys_function, |
227 | ISKU_BIN_ATTR_RW(keys_easyzone, KEYS_EASYZONE), | 230 | &bin_attr_keys_easyzone, |
228 | ISKU_BIN_ATTR_RW(keys_media, KEYS_MEDIA), | 231 | &bin_attr_keys_media, |
229 | ISKU_BIN_ATTR_RW(keys_thumbster, KEYS_THUMBSTER), | 232 | &bin_attr_keys_thumbster, |
230 | ISKU_BIN_ATTR_RW(keys_macro, KEYS_MACRO), | 233 | &bin_attr_keys_macro, |
231 | ISKU_BIN_ATTR_RW(keys_capslock, KEYS_CAPSLOCK), | 234 | &bin_attr_keys_capslock, |
232 | ISKU_BIN_ATTR_RW(light, LIGHT), | 235 | &bin_attr_light, |
233 | ISKU_BIN_ATTR_RW(key_mask, KEY_MASK), | 236 | &bin_attr_key_mask, |
234 | ISKU_BIN_ATTR_RW(last_set, LAST_SET), | 237 | &bin_attr_last_set, |
235 | ISKU_BIN_ATTR_W(talk, TALK), | 238 | &bin_attr_talk, |
236 | ISKU_BIN_ATTR_W(talkfx, TALKFX), | 239 | &bin_attr_talkfx, |
237 | ISKU_BIN_ATTR_R(info, INFO), | 240 | &bin_attr_control, |
238 | ISKU_BIN_ATTR_W(control, CONTROL), | 241 | &bin_attr_reset, |
239 | ISKU_BIN_ATTR_W(reset, RESET), | 242 | &bin_attr_info, |
240 | __ATTR_NULL | 243 | NULL, |
244 | }; | ||
245 | |||
246 | static const struct attribute_group isku_group = { | ||
247 | .attrs = isku_attrs, | ||
248 | .bin_attrs = isku_bin_attributes, | ||
249 | }; | ||
250 | |||
251 | static const struct attribute_group *isku_groups[] = { | ||
252 | &isku_group, | ||
253 | NULL, | ||
241 | }; | 254 | }; |
242 | 255 | ||
243 | static int isku_init_isku_device_struct(struct usb_device *usb_dev, | 256 | static int isku_init_isku_device_struct(struct usb_device *usb_dev, |
@@ -427,8 +440,7 @@ static int __init isku_init(void) | |||
427 | isku_class = class_create(THIS_MODULE, "isku"); | 440 | isku_class = class_create(THIS_MODULE, "isku"); |
428 | if (IS_ERR(isku_class)) | 441 | if (IS_ERR(isku_class)) |
429 | return PTR_ERR(isku_class); | 442 | return PTR_ERR(isku_class); |
430 | isku_class->dev_attrs = isku_attributes; | 443 | isku_class->dev_groups = isku_groups; |
431 | isku_class->dev_bin_attrs = isku_bin_attributes; | ||
432 | 444 | ||
433 | retval = hid_register_driver(&isku_driver); | 445 | retval = hid_register_driver(&isku_driver); |
434 | if (retval) | 446 | if (retval) |
diff --git a/drivers/hid/hid-roccat-kone.c b/drivers/hid/hid-roccat-kone.c index 7fae070788fa..6e614a85f175 100644 --- a/drivers/hid/hid-roccat-kone.c +++ b/drivers/hid/hid-roccat-kone.c | |||
@@ -324,6 +324,8 @@ static ssize_t kone_sysfs_write_settings(struct file *fp, struct kobject *kobj, | |||
324 | 324 | ||
325 | return sizeof(struct kone_settings); | 325 | return sizeof(struct kone_settings); |
326 | } | 326 | } |
327 | static BIN_ATTR(settings, 0660, kone_sysfs_read_settings, | ||
328 | kone_sysfs_write_settings, sizeof(struct kone_settings)); | ||
327 | 329 | ||
328 | static ssize_t kone_sysfs_read_profilex(struct file *fp, | 330 | static ssize_t kone_sysfs_read_profilex(struct file *fp, |
329 | struct kobject *kobj, struct bin_attribute *attr, | 331 | struct kobject *kobj, struct bin_attribute *attr, |
@@ -378,6 +380,19 @@ static ssize_t kone_sysfs_write_profilex(struct file *fp, | |||
378 | 380 | ||
379 | return sizeof(struct kone_profile); | 381 | return sizeof(struct kone_profile); |
380 | } | 382 | } |
383 | #define PROFILE_ATTR(number) \ | ||
384 | static struct bin_attribute bin_attr_profile##number = { \ | ||
385 | .attr = { .name = "profile##number", .mode = 0660 }, \ | ||
386 | .size = sizeof(struct kone_profile), \ | ||
387 | .read = kone_sysfs_read_profilex, \ | ||
388 | .write = kone_sysfs_write_profilex, \ | ||
389 | .private = &profile_numbers[number-1], \ | ||
390 | }; | ||
391 | PROFILE_ATTR(1); | ||
392 | PROFILE_ATTR(2); | ||
393 | PROFILE_ATTR(3); | ||
394 | PROFILE_ATTR(4); | ||
395 | PROFILE_ATTR(5); | ||
381 | 396 | ||
382 | static ssize_t kone_sysfs_show_actual_profile(struct device *dev, | 397 | static ssize_t kone_sysfs_show_actual_profile(struct device *dev, |
383 | struct device_attribute *attr, char *buf) | 398 | struct device_attribute *attr, char *buf) |
@@ -386,6 +401,7 @@ static ssize_t kone_sysfs_show_actual_profile(struct device *dev, | |||
386 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 401 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
387 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile); | 402 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_profile); |
388 | } | 403 | } |
404 | static DEVICE_ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL); | ||
389 | 405 | ||
390 | static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, | 406 | static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, |
391 | struct device_attribute *attr, char *buf) | 407 | struct device_attribute *attr, char *buf) |
@@ -394,6 +410,7 @@ static ssize_t kone_sysfs_show_actual_dpi(struct device *dev, | |||
394 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 410 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
395 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi); | 411 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->actual_dpi); |
396 | } | 412 | } |
413 | static DEVICE_ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL); | ||
397 | 414 | ||
398 | /* weight is read each time, since we don't get informed when it's changed */ | 415 | /* weight is read each time, since we don't get informed when it's changed */ |
399 | static ssize_t kone_sysfs_show_weight(struct device *dev, | 416 | static ssize_t kone_sysfs_show_weight(struct device *dev, |
@@ -416,6 +433,7 @@ static ssize_t kone_sysfs_show_weight(struct device *dev, | |||
416 | return retval; | 433 | return retval; |
417 | return snprintf(buf, PAGE_SIZE, "%d\n", weight); | 434 | return snprintf(buf, PAGE_SIZE, "%d\n", weight); |
418 | } | 435 | } |
436 | static DEVICE_ATTR(weight, 0440, kone_sysfs_show_weight, NULL); | ||
419 | 437 | ||
420 | static ssize_t kone_sysfs_show_firmware_version(struct device *dev, | 438 | static ssize_t kone_sysfs_show_firmware_version(struct device *dev, |
421 | struct device_attribute *attr, char *buf) | 439 | struct device_attribute *attr, char *buf) |
@@ -424,6 +442,8 @@ static ssize_t kone_sysfs_show_firmware_version(struct device *dev, | |||
424 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 442 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
425 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version); | 443 | return snprintf(buf, PAGE_SIZE, "%d\n", kone->firmware_version); |
426 | } | 444 | } |
445 | static DEVICE_ATTR(firmware_version, 0440, kone_sysfs_show_firmware_version, | ||
446 | NULL); | ||
427 | 447 | ||
428 | static ssize_t kone_sysfs_show_tcu(struct device *dev, | 448 | static ssize_t kone_sysfs_show_tcu(struct device *dev, |
429 | struct device_attribute *attr, char *buf) | 449 | struct device_attribute *attr, char *buf) |
@@ -524,6 +544,7 @@ exit_unlock: | |||
524 | mutex_unlock(&kone->kone_lock); | 544 | mutex_unlock(&kone->kone_lock); |
525 | return retval; | 545 | return retval; |
526 | } | 546 | } |
547 | static DEVICE_ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu); | ||
527 | 548 | ||
528 | static ssize_t kone_sysfs_show_startup_profile(struct device *dev, | 549 | static ssize_t kone_sysfs_show_startup_profile(struct device *dev, |
529 | struct device_attribute *attr, char *buf) | 550 | struct device_attribute *attr, char *buf) |
@@ -570,15 +591,17 @@ static ssize_t kone_sysfs_set_startup_profile(struct device *dev, | |||
570 | mutex_unlock(&kone->kone_lock); | 591 | mutex_unlock(&kone->kone_lock); |
571 | return size; | 592 | return size; |
572 | } | 593 | } |
594 | static DEVICE_ATTR(startup_profile, 0660, kone_sysfs_show_startup_profile, | ||
595 | kone_sysfs_set_startup_profile); | ||
573 | 596 | ||
574 | static struct device_attribute kone_attributes[] = { | 597 | static struct attribute *kone_attrs[] = { |
575 | /* | 598 | /* |
576 | * Read actual dpi settings. | 599 | * Read actual dpi settings. |
577 | * Returns raw value for further processing. Refer to enum | 600 | * Returns raw value for further processing. Refer to enum |
578 | * kone_polling_rates to get real value. | 601 | * kone_polling_rates to get real value. |
579 | */ | 602 | */ |
580 | __ATTR(actual_dpi, 0440, kone_sysfs_show_actual_dpi, NULL), | 603 | &dev_attr_actual_dpi.attr, |
581 | __ATTR(actual_profile, 0440, kone_sysfs_show_actual_profile, NULL), | 604 | &dev_attr_actual_profile.attr, |
582 | 605 | ||
583 | /* | 606 | /* |
584 | * The mouse can be equipped with one of four supplied weights from 5 | 607 | * The mouse can be equipped with one of four supplied weights from 5 |
@@ -587,7 +610,7 @@ static struct device_attribute kone_attributes[] = { | |||
587 | * by software. Refer to enum kone_weights to get corresponding real | 610 | * by software. Refer to enum kone_weights to get corresponding real |
588 | * weight. | 611 | * weight. |
589 | */ | 612 | */ |
590 | __ATTR(weight, 0440, kone_sysfs_show_weight, NULL), | 613 | &dev_attr_weight.attr, |
591 | 614 | ||
592 | /* | 615 | /* |
593 | * Prints firmware version stored in mouse as integer. | 616 | * Prints firmware version stored in mouse as integer. |
@@ -595,66 +618,38 @@ static struct device_attribute kone_attributes[] = { | |||
595 | * to get the real version number the decimal point has to be shifted 2 | 618 | * to get the real version number the decimal point has to be shifted 2 |
596 | * positions to the left. E.g. a value of 138 means 1.38. | 619 | * positions to the left. E.g. a value of 138 means 1.38. |
597 | */ | 620 | */ |
598 | __ATTR(firmware_version, 0440, | 621 | &dev_attr_firmware_version.attr, |
599 | kone_sysfs_show_firmware_version, NULL), | ||
600 | 622 | ||
601 | /* | 623 | /* |
602 | * Prints state of Tracking Control Unit as number where 0 = off and | 624 | * Prints state of Tracking Control Unit as number where 0 = off and |
603 | * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and | 625 | * 1 = on. Writing 0 deactivates tcu and writing 1 calibrates and |
604 | * activates the tcu | 626 | * activates the tcu |
605 | */ | 627 | */ |
606 | __ATTR(tcu, 0660, kone_sysfs_show_tcu, kone_sysfs_set_tcu), | 628 | &dev_attr_tcu.attr, |
607 | 629 | ||
608 | /* Prints and takes the number of the profile the mouse starts with */ | 630 | /* Prints and takes the number of the profile the mouse starts with */ |
609 | __ATTR(startup_profile, 0660, | 631 | &dev_attr_startup_profile.attr, |
610 | kone_sysfs_show_startup_profile, | 632 | NULL, |
611 | kone_sysfs_set_startup_profile), | 633 | }; |
612 | __ATTR_NULL | 634 | |
635 | static struct bin_attribute *kone_bin_attributes[] = { | ||
636 | &bin_attr_settings, | ||
637 | &bin_attr_profile1, | ||
638 | &bin_attr_profile2, | ||
639 | &bin_attr_profile3, | ||
640 | &bin_attr_profile4, | ||
641 | &bin_attr_profile5, | ||
642 | NULL, | ||
643 | }; | ||
644 | |||
645 | static const struct attribute_group kone_group = { | ||
646 | .attrs = kone_attrs, | ||
647 | .bin_attrs = kone_bin_attributes, | ||
613 | }; | 648 | }; |
614 | 649 | ||
615 | static struct bin_attribute kone_bin_attributes[] = { | 650 | static const struct attribute_group *kone_groups[] = { |
616 | { | 651 | &kone_group, |
617 | .attr = { .name = "settings", .mode = 0660 }, | 652 | NULL, |
618 | .size = sizeof(struct kone_settings), | ||
619 | .read = kone_sysfs_read_settings, | ||
620 | .write = kone_sysfs_write_settings | ||
621 | }, | ||
622 | { | ||
623 | .attr = { .name = "profile1", .mode = 0660 }, | ||
624 | .size = sizeof(struct kone_profile), | ||
625 | .read = kone_sysfs_read_profilex, | ||
626 | .write = kone_sysfs_write_profilex, | ||
627 | .private = &profile_numbers[0] | ||
628 | }, | ||
629 | { | ||
630 | .attr = { .name = "profile2", .mode = 0660 }, | ||
631 | .size = sizeof(struct kone_profile), | ||
632 | .read = kone_sysfs_read_profilex, | ||
633 | .write = kone_sysfs_write_profilex, | ||
634 | .private = &profile_numbers[1] | ||
635 | }, | ||
636 | { | ||
637 | .attr = { .name = "profile3", .mode = 0660 }, | ||
638 | .size = sizeof(struct kone_profile), | ||
639 | .read = kone_sysfs_read_profilex, | ||
640 | .write = kone_sysfs_write_profilex, | ||
641 | .private = &profile_numbers[2] | ||
642 | }, | ||
643 | { | ||
644 | .attr = { .name = "profile4", .mode = 0660 }, | ||
645 | .size = sizeof(struct kone_profile), | ||
646 | .read = kone_sysfs_read_profilex, | ||
647 | .write = kone_sysfs_write_profilex, | ||
648 | .private = &profile_numbers[3] | ||
649 | }, | ||
650 | { | ||
651 | .attr = { .name = "profile5", .mode = 0660 }, | ||
652 | .size = sizeof(struct kone_profile), | ||
653 | .read = kone_sysfs_read_profilex, | ||
654 | .write = kone_sysfs_write_profilex, | ||
655 | .private = &profile_numbers[4] | ||
656 | }, | ||
657 | __ATTR_NULL | ||
658 | }; | 653 | }; |
659 | 654 | ||
660 | static int kone_init_kone_device_struct(struct usb_device *usb_dev, | 655 | static int kone_init_kone_device_struct(struct usb_device *usb_dev, |
@@ -891,8 +886,7 @@ static int __init kone_init(void) | |||
891 | kone_class = class_create(THIS_MODULE, "kone"); | 886 | kone_class = class_create(THIS_MODULE, "kone"); |
892 | if (IS_ERR(kone_class)) | 887 | if (IS_ERR(kone_class)) |
893 | return PTR_ERR(kone_class); | 888 | return PTR_ERR(kone_class); |
894 | kone_class->dev_attrs = kone_attributes; | 889 | kone_class->dev_groups = kone_groups; |
895 | kone_class->dev_bin_attrs = kone_bin_attributes; | ||
896 | 890 | ||
897 | retval = hid_register_driver(&kone_driver); | 891 | retval = hid_register_driver(&kone_driver); |
898 | if (retval) | 892 | if (retval) |
diff --git a/drivers/hid/hid-roccat-koneplus.c b/drivers/hid/hid-roccat-koneplus.c index 6a48fa3c7da9..db4d8b6a2542 100644 --- a/drivers/hid/hid-roccat-koneplus.c +++ b/drivers/hid/hid-roccat-koneplus.c | |||
@@ -156,7 +156,8 @@ KONEPLUS_SYSFS_W(thingy, THINGY) \ | |||
156 | KONEPLUS_SYSFS_R(thingy, THINGY) | 156 | KONEPLUS_SYSFS_R(thingy, THINGY) |
157 | 157 | ||
158 | #define KONEPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \ | 158 | #define KONEPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
159 | { \ | 159 | KONEPLUS_SYSFS_RW(thingy, THINGY); \ |
160 | static struct bin_attribute bin_attr_##thingy = { \ | ||
160 | .attr = { .name = #thingy, .mode = 0660 }, \ | 161 | .attr = { .name = #thingy, .mode = 0660 }, \ |
161 | .size = KONEPLUS_SIZE_ ## THINGY, \ | 162 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
162 | .read = koneplus_sysfs_read_ ## thingy, \ | 163 | .read = koneplus_sysfs_read_ ## thingy, \ |
@@ -164,28 +165,29 @@ KONEPLUS_SYSFS_R(thingy, THINGY) | |||
164 | } | 165 | } |
165 | 166 | ||
166 | #define KONEPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \ | 167 | #define KONEPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \ |
167 | { \ | 168 | KONEPLUS_SYSFS_R(thingy, THINGY); \ |
169 | static struct bin_attribute bin_attr_##thingy = { \ | ||
168 | .attr = { .name = #thingy, .mode = 0440 }, \ | 170 | .attr = { .name = #thingy, .mode = 0440 }, \ |
169 | .size = KONEPLUS_SIZE_ ## THINGY, \ | 171 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
170 | .read = koneplus_sysfs_read_ ## thingy, \ | 172 | .read = koneplus_sysfs_read_ ## thingy, \ |
171 | } | 173 | } |
172 | 174 | ||
173 | #define KONEPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \ | 175 | #define KONEPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
174 | { \ | 176 | KONEPLUS_SYSFS_W(thingy, THINGY); \ |
177 | static struct bin_attribute bin_attr_##thingy = { \ | ||
175 | .attr = { .name = #thingy, .mode = 0220 }, \ | 178 | .attr = { .name = #thingy, .mode = 0220 }, \ |
176 | .size = KONEPLUS_SIZE_ ## THINGY, \ | 179 | .size = KONEPLUS_SIZE_ ## THINGY, \ |
177 | .write = koneplus_sysfs_write_ ## thingy \ | 180 | .write = koneplus_sysfs_write_ ## thingy \ |
178 | } | 181 | } |
179 | 182 | KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL); | |
180 | KONEPLUS_SYSFS_W(control, CONTROL) | 183 | KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK); |
181 | KONEPLUS_SYSFS_RW(info, INFO) | 184 | KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO); |
182 | KONEPLUS_SYSFS_W(talk, TALK) | 185 | KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE); |
183 | KONEPLUS_SYSFS_W(macro, MACRO) | 186 | KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO); |
184 | KONEPLUS_SYSFS_RW(sensor, SENSOR) | 187 | KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR); |
185 | KONEPLUS_SYSFS_RW(tcu, TCU) | 188 | KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU); |
186 | KONEPLUS_SYSFS_R(tcu_image, TCU_IMAGE) | 189 | KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS); |
187 | KONEPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS) | 190 | KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS); |
188 | KONEPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) | ||
189 | 191 | ||
190 | static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, | 192 | static ssize_t koneplus_sysfs_read_profilex_settings(struct file *fp, |
191 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 193 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
@@ -225,6 +227,25 @@ static ssize_t koneplus_sysfs_read_profilex_buttons(struct file *fp, | |||
225 | KONEPLUS_COMMAND_PROFILE_BUTTONS); | 227 | KONEPLUS_COMMAND_PROFILE_BUTTONS); |
226 | } | 228 | } |
227 | 229 | ||
230 | #define PROFILE_ATTR(number) \ | ||
231 | static struct bin_attribute bin_attr_profile##number##_settings = { \ | ||
232 | .attr = { .name = "profile##number##_settings", .mode = 0440 }, \ | ||
233 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, \ | ||
234 | .read = koneplus_sysfs_read_profilex_settings, \ | ||
235 | .private = &profile_numbers[number-1], \ | ||
236 | }; \ | ||
237 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ | ||
238 | .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ | ||
239 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, \ | ||
240 | .read = koneplus_sysfs_read_profilex_buttons, \ | ||
241 | .private = &profile_numbers[number-1], \ | ||
242 | }; | ||
243 | PROFILE_ATTR(1); | ||
244 | PROFILE_ATTR(2); | ||
245 | PROFILE_ATTR(3); | ||
246 | PROFILE_ATTR(4); | ||
247 | PROFILE_ATTR(5); | ||
248 | |||
228 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, | 249 | static ssize_t koneplus_sysfs_show_actual_profile(struct device *dev, |
229 | struct device_attribute *attr, char *buf) | 250 | struct device_attribute *attr, char *buf) |
230 | { | 251 | { |
@@ -274,6 +295,12 @@ static ssize_t koneplus_sysfs_set_actual_profile(struct device *dev, | |||
274 | 295 | ||
275 | return size; | 296 | return size; |
276 | } | 297 | } |
298 | static DEVICE_ATTR(actual_profile, 0660, | ||
299 | koneplus_sysfs_show_actual_profile, | ||
300 | koneplus_sysfs_set_actual_profile); | ||
301 | static DEVICE_ATTR(startup_profile, 0660, | ||
302 | koneplus_sysfs_show_actual_profile, | ||
303 | koneplus_sysfs_set_actual_profile); | ||
277 | 304 | ||
278 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, | 305 | static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, |
279 | struct device_attribute *attr, char *buf) | 306 | struct device_attribute *attr, char *buf) |
@@ -293,90 +320,47 @@ static ssize_t koneplus_sysfs_show_firmware_version(struct device *dev, | |||
293 | 320 | ||
294 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); | 321 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); |
295 | } | 322 | } |
323 | static DEVICE_ATTR(firmware_version, 0440, | ||
324 | koneplus_sysfs_show_firmware_version, NULL); | ||
325 | |||
326 | static struct attribute *koneplus_attrs[] = { | ||
327 | &dev_attr_actual_profile.attr, | ||
328 | &dev_attr_startup_profile.attr, | ||
329 | &dev_attr_firmware_version.attr, | ||
330 | NULL, | ||
331 | }; | ||
332 | |||
333 | static struct bin_attribute *koneplus_bin_attributes[] = { | ||
334 | &bin_attr_control, | ||
335 | &bin_attr_talk, | ||
336 | &bin_attr_macro, | ||
337 | &bin_attr_tcu_image, | ||
338 | &bin_attr_info, | ||
339 | &bin_attr_sensor, | ||
340 | &bin_attr_tcu, | ||
341 | &bin_attr_profile_settings, | ||
342 | &bin_attr_profile_buttons, | ||
343 | &bin_attr_profile1_settings, | ||
344 | &bin_attr_profile2_settings, | ||
345 | &bin_attr_profile3_settings, | ||
346 | &bin_attr_profile4_settings, | ||
347 | &bin_attr_profile5_settings, | ||
348 | &bin_attr_profile1_buttons, | ||
349 | &bin_attr_profile2_buttons, | ||
350 | &bin_attr_profile3_buttons, | ||
351 | &bin_attr_profile4_buttons, | ||
352 | &bin_attr_profile5_buttons, | ||
353 | NULL, | ||
354 | }; | ||
296 | 355 | ||
297 | static struct device_attribute koneplus_attributes[] = { | 356 | static const struct attribute_group koneplus_group = { |
298 | __ATTR(actual_profile, 0660, | 357 | .attrs = koneplus_attrs, |
299 | koneplus_sysfs_show_actual_profile, | 358 | .bin_attrs = koneplus_bin_attributes, |
300 | koneplus_sysfs_set_actual_profile), | ||
301 | __ATTR(startup_profile, 0660, | ||
302 | koneplus_sysfs_show_actual_profile, | ||
303 | koneplus_sysfs_set_actual_profile), | ||
304 | __ATTR(firmware_version, 0440, | ||
305 | koneplus_sysfs_show_firmware_version, NULL), | ||
306 | __ATTR_NULL | ||
307 | }; | 359 | }; |
308 | 360 | ||
309 | static struct bin_attribute koneplus_bin_attributes[] = { | 361 | static const struct attribute_group *koneplus_groups[] = { |
310 | KONEPLUS_BIN_ATTRIBUTE_W(control, CONTROL), | 362 | &koneplus_group, |
311 | KONEPLUS_BIN_ATTRIBUTE_RW(info, INFO), | 363 | NULL, |
312 | KONEPLUS_BIN_ATTRIBUTE_W(talk, TALK), | ||
313 | KONEPLUS_BIN_ATTRIBUTE_W(macro, MACRO), | ||
314 | KONEPLUS_BIN_ATTRIBUTE_RW(sensor, SENSOR), | ||
315 | KONEPLUS_BIN_ATTRIBUTE_RW(tcu, TCU), | ||
316 | KONEPLUS_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE), | ||
317 | KONEPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), | ||
318 | KONEPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), | ||
319 | { | ||
320 | .attr = { .name = "profile1_settings", .mode = 0440 }, | ||
321 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, | ||
322 | .read = koneplus_sysfs_read_profilex_settings, | ||
323 | .private = &profile_numbers[0] | ||
324 | }, | ||
325 | { | ||
326 | .attr = { .name = "profile2_settings", .mode = 0440 }, | ||
327 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, | ||
328 | .read = koneplus_sysfs_read_profilex_settings, | ||
329 | .private = &profile_numbers[1] | ||
330 | }, | ||
331 | { | ||
332 | .attr = { .name = "profile3_settings", .mode = 0440 }, | ||
333 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, | ||
334 | .read = koneplus_sysfs_read_profilex_settings, | ||
335 | .private = &profile_numbers[2] | ||
336 | }, | ||
337 | { | ||
338 | .attr = { .name = "profile4_settings", .mode = 0440 }, | ||
339 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, | ||
340 | .read = koneplus_sysfs_read_profilex_settings, | ||
341 | .private = &profile_numbers[3] | ||
342 | }, | ||
343 | { | ||
344 | .attr = { .name = "profile5_settings", .mode = 0440 }, | ||
345 | .size = KONEPLUS_SIZE_PROFILE_SETTINGS, | ||
346 | .read = koneplus_sysfs_read_profilex_settings, | ||
347 | .private = &profile_numbers[4] | ||
348 | }, | ||
349 | { | ||
350 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | ||
351 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, | ||
352 | .read = koneplus_sysfs_read_profilex_buttons, | ||
353 | .private = &profile_numbers[0] | ||
354 | }, | ||
355 | { | ||
356 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | ||
357 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, | ||
358 | .read = koneplus_sysfs_read_profilex_buttons, | ||
359 | .private = &profile_numbers[1] | ||
360 | }, | ||
361 | { | ||
362 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | ||
363 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, | ||
364 | .read = koneplus_sysfs_read_profilex_buttons, | ||
365 | .private = &profile_numbers[2] | ||
366 | }, | ||
367 | { | ||
368 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | ||
369 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, | ||
370 | .read = koneplus_sysfs_read_profilex_buttons, | ||
371 | .private = &profile_numbers[3] | ||
372 | }, | ||
373 | { | ||
374 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | ||
375 | .size = KONEPLUS_SIZE_PROFILE_BUTTONS, | ||
376 | .read = koneplus_sysfs_read_profilex_buttons, | ||
377 | .private = &profile_numbers[4] | ||
378 | }, | ||
379 | __ATTR_NULL | ||
380 | }; | 364 | }; |
381 | 365 | ||
382 | static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, | 366 | static int koneplus_init_koneplus_device_struct(struct usb_device *usb_dev, |
@@ -572,8 +556,7 @@ static int __init koneplus_init(void) | |||
572 | koneplus_class = class_create(THIS_MODULE, "koneplus"); | 556 | koneplus_class = class_create(THIS_MODULE, "koneplus"); |
573 | if (IS_ERR(koneplus_class)) | 557 | if (IS_ERR(koneplus_class)) |
574 | return PTR_ERR(koneplus_class); | 558 | return PTR_ERR(koneplus_class); |
575 | koneplus_class->dev_attrs = koneplus_attributes; | 559 | koneplus_class->dev_groups = koneplus_groups; |
576 | koneplus_class->dev_bin_attrs = koneplus_bin_attributes; | ||
577 | 560 | ||
578 | retval = hid_register_driver(&koneplus_driver); | 561 | retval = hid_register_driver(&koneplus_driver); |
579 | if (retval) | 562 | if (retval) |
diff --git a/drivers/hid/hid-roccat-konepure.c b/drivers/hid/hid-roccat-konepure.c index c79d0b06c143..fa02b1f44979 100644 --- a/drivers/hid/hid-roccat-konepure.c +++ b/drivers/hid/hid-roccat-konepure.c | |||
@@ -94,7 +94,8 @@ KONEPURE_SYSFS_W(thingy, THINGY) \ | |||
94 | KONEPURE_SYSFS_R(thingy, THINGY) | 94 | KONEPURE_SYSFS_R(thingy, THINGY) |
95 | 95 | ||
96 | #define KONEPURE_BIN_ATTRIBUTE_RW(thingy, THINGY) \ | 96 | #define KONEPURE_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
97 | { \ | 97 | KONEPURE_SYSFS_RW(thingy, THINGY); \ |
98 | static struct bin_attribute bin_attr_##thingy = { \ | ||
98 | .attr = { .name = #thingy, .mode = 0660 }, \ | 99 | .attr = { .name = #thingy, .mode = 0660 }, \ |
99 | .size = KONEPURE_SIZE_ ## THINGY, \ | 100 | .size = KONEPURE_SIZE_ ## THINGY, \ |
100 | .read = konepure_sysfs_read_ ## thingy, \ | 101 | .read = konepure_sysfs_read_ ## thingy, \ |
@@ -102,44 +103,56 @@ KONEPURE_SYSFS_R(thingy, THINGY) | |||
102 | } | 103 | } |
103 | 104 | ||
104 | #define KONEPURE_BIN_ATTRIBUTE_R(thingy, THINGY) \ | 105 | #define KONEPURE_BIN_ATTRIBUTE_R(thingy, THINGY) \ |
105 | { \ | 106 | KONEPURE_SYSFS_R(thingy, THINGY); \ |
107 | static struct bin_attribute bin_attr_##thingy = { \ | ||
106 | .attr = { .name = #thingy, .mode = 0440 }, \ | 108 | .attr = { .name = #thingy, .mode = 0440 }, \ |
107 | .size = KONEPURE_SIZE_ ## THINGY, \ | 109 | .size = KONEPURE_SIZE_ ## THINGY, \ |
108 | .read = konepure_sysfs_read_ ## thingy, \ | 110 | .read = konepure_sysfs_read_ ## thingy, \ |
109 | } | 111 | } |
110 | 112 | ||
111 | #define KONEPURE_BIN_ATTRIBUTE_W(thingy, THINGY) \ | 113 | #define KONEPURE_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
112 | { \ | 114 | KONEPURE_SYSFS_W(thingy, THINGY); \ |
115 | static struct bin_attribute bin_attr_##thingy = { \ | ||
113 | .attr = { .name = #thingy, .mode = 0220 }, \ | 116 | .attr = { .name = #thingy, .mode = 0220 }, \ |
114 | .size = KONEPURE_SIZE_ ## THINGY, \ | 117 | .size = KONEPURE_SIZE_ ## THINGY, \ |
115 | .write = konepure_sysfs_write_ ## thingy \ | 118 | .write = konepure_sysfs_write_ ## thingy \ |
116 | } | 119 | } |
117 | 120 | ||
118 | KONEPURE_SYSFS_RW(actual_profile, ACTUAL_PROFILE) | 121 | KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE); |
119 | KONEPURE_SYSFS_W(control, CONTROL) | 122 | KONEPURE_BIN_ATTRIBUTE_RW(info, INFO); |
120 | KONEPURE_SYSFS_RW(info, INFO) | 123 | KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR); |
121 | KONEPURE_SYSFS_W(talk, TALK) | 124 | KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU); |
122 | KONEPURE_SYSFS_W(macro, MACRO) | 125 | KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS); |
123 | KONEPURE_SYSFS_RW(sensor, SENSOR) | 126 | KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS); |
124 | KONEPURE_SYSFS_RW(tcu, TCU) | 127 | KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL); |
125 | KONEPURE_SYSFS_R(tcu_image, TCU_IMAGE) | 128 | KONEPURE_BIN_ATTRIBUTE_W(talk, TALK); |
126 | KONEPURE_SYSFS_RW(profile_settings, PROFILE_SETTINGS) | 129 | KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO); |
127 | KONEPURE_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) | 130 | KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE); |
128 | 131 | ||
129 | static struct bin_attribute konepure_bin_attributes[] = { | 132 | static struct bin_attribute *konepure_bin_attributes[] = { |
130 | KONEPURE_BIN_ATTRIBUTE_RW(actual_profile, ACTUAL_PROFILE), | 133 | &bin_attr_actual_profile, |
131 | KONEPURE_BIN_ATTRIBUTE_W(control, CONTROL), | 134 | &bin_attr_info, |
132 | KONEPURE_BIN_ATTRIBUTE_RW(info, INFO), | 135 | &bin_attr_sensor, |
133 | KONEPURE_BIN_ATTRIBUTE_W(talk, TALK), | 136 | &bin_attr_tcu, |
134 | KONEPURE_BIN_ATTRIBUTE_W(macro, MACRO), | 137 | &bin_attr_profile_settings, |
135 | KONEPURE_BIN_ATTRIBUTE_RW(sensor, SENSOR), | 138 | &bin_attr_profile_buttons, |
136 | KONEPURE_BIN_ATTRIBUTE_RW(tcu, TCU), | 139 | &bin_attr_control, |
137 | KONEPURE_BIN_ATTRIBUTE_R(tcu_image, TCU_IMAGE), | 140 | &bin_attr_talk, |
138 | KONEPURE_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), | 141 | &bin_attr_macro, |
139 | KONEPURE_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), | 142 | &bin_attr_tcu_image, |
140 | __ATTR_NULL | 143 | NULL, |
144 | }; | ||
145 | |||
146 | static const struct attribute_group konepure_group = { | ||
147 | .bin_attrs = konepure_bin_attributes, | ||
148 | }; | ||
149 | |||
150 | static const struct attribute_group *konepure_groups[] = { | ||
151 | &konepure_group, | ||
152 | NULL, | ||
141 | }; | 153 | }; |
142 | 154 | ||
155 | |||
143 | static int konepure_init_konepure_device_struct(struct usb_device *usb_dev, | 156 | static int konepure_init_konepure_device_struct(struct usb_device *usb_dev, |
144 | struct konepure_device *konepure) | 157 | struct konepure_device *konepure) |
145 | { | 158 | { |
@@ -282,7 +295,7 @@ static int __init konepure_init(void) | |||
282 | konepure_class = class_create(THIS_MODULE, "konepure"); | 295 | konepure_class = class_create(THIS_MODULE, "konepure"); |
283 | if (IS_ERR(konepure_class)) | 296 | if (IS_ERR(konepure_class)) |
284 | return PTR_ERR(konepure_class); | 297 | return PTR_ERR(konepure_class); |
285 | konepure_class->dev_bin_attrs = konepure_bin_attributes; | 298 | konepure_class->dev_groups = konepure_groups; |
286 | 299 | ||
287 | retval = hid_register_driver(&konepure_driver); | 300 | retval = hid_register_driver(&konepure_driver); |
288 | if (retval) | 301 | if (retval) |
diff --git a/drivers/hid/hid-roccat-kovaplus.c b/drivers/hid/hid-roccat-kovaplus.c index b8b37789b864..8a0f2993411f 100644 --- a/drivers/hid/hid-roccat-kovaplus.c +++ b/drivers/hid/hid-roccat-kovaplus.c | |||
@@ -197,31 +197,25 @@ KOVAPLUS_SYSFS_W(thingy, THINGY) \ | |||
197 | KOVAPLUS_SYSFS_R(thingy, THINGY) | 197 | KOVAPLUS_SYSFS_R(thingy, THINGY) |
198 | 198 | ||
199 | #define KOVAPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \ | 199 | #define KOVAPLUS_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
200 | { \ | 200 | KOVAPLUS_SYSFS_RW(thingy, THINGY); \ |
201 | static struct bin_attribute bin_attr_##thingy = { \ | ||
201 | .attr = { .name = #thingy, .mode = 0660 }, \ | 202 | .attr = { .name = #thingy, .mode = 0660 }, \ |
202 | .size = KOVAPLUS_SIZE_ ## THINGY, \ | 203 | .size = KOVAPLUS_SIZE_ ## THINGY, \ |
203 | .read = kovaplus_sysfs_read_ ## thingy, \ | 204 | .read = kovaplus_sysfs_read_ ## thingy, \ |
204 | .write = kovaplus_sysfs_write_ ## thingy \ | 205 | .write = kovaplus_sysfs_write_ ## thingy \ |
205 | } | 206 | } |
206 | 207 | ||
207 | #define KOVAPLUS_BIN_ATTRIBUTE_R(thingy, THINGY) \ | ||
208 | { \ | ||
209 | .attr = { .name = #thingy, .mode = 0440 }, \ | ||
210 | .size = KOVAPLUS_SIZE_ ## THINGY, \ | ||
211 | .read = kovaplus_sysfs_read_ ## thingy, \ | ||
212 | } | ||
213 | |||
214 | #define KOVAPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \ | 208 | #define KOVAPLUS_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
215 | { \ | 209 | KOVAPLUS_SYSFS_W(thingy, THINGY); \ |
210 | static struct bin_attribute bin_attr_##thingy = { \ | ||
216 | .attr = { .name = #thingy, .mode = 0220 }, \ | 211 | .attr = { .name = #thingy, .mode = 0220 }, \ |
217 | .size = KOVAPLUS_SIZE_ ## THINGY, \ | 212 | .size = KOVAPLUS_SIZE_ ## THINGY, \ |
218 | .write = kovaplus_sysfs_write_ ## thingy \ | 213 | .write = kovaplus_sysfs_write_ ## thingy \ |
219 | } | 214 | } |
220 | 215 | KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL); | |
221 | KOVAPLUS_SYSFS_W(control, CONTROL) | 216 | KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO); |
222 | KOVAPLUS_SYSFS_RW(info, INFO) | 217 | KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS); |
223 | KOVAPLUS_SYSFS_RW(profile_settings, PROFILE_SETTINGS) | 218 | KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS); |
224 | KOVAPLUS_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) | ||
225 | 219 | ||
226 | static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp, | 220 | static ssize_t kovaplus_sysfs_read_profilex_settings(struct file *fp, |
227 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 221 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
@@ -261,6 +255,25 @@ static ssize_t kovaplus_sysfs_read_profilex_buttons(struct file *fp, | |||
261 | KOVAPLUS_COMMAND_PROFILE_BUTTONS); | 255 | KOVAPLUS_COMMAND_PROFILE_BUTTONS); |
262 | } | 256 | } |
263 | 257 | ||
258 | #define PROFILE_ATTR(number) \ | ||
259 | static struct bin_attribute bin_attr_profile##number##_settings = { \ | ||
260 | .attr = { .name = "profile##number##_settings", .mode = 0440 }, \ | ||
261 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, \ | ||
262 | .read = kovaplus_sysfs_read_profilex_settings, \ | ||
263 | .private = &profile_numbers[number-1], \ | ||
264 | }; \ | ||
265 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ | ||
266 | .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ | ||
267 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, \ | ||
268 | .read = kovaplus_sysfs_read_profilex_buttons, \ | ||
269 | .private = &profile_numbers[number-1], \ | ||
270 | }; | ||
271 | PROFILE_ATTR(1); | ||
272 | PROFILE_ATTR(2); | ||
273 | PROFILE_ATTR(3); | ||
274 | PROFILE_ATTR(4); | ||
275 | PROFILE_ATTR(5); | ||
276 | |||
264 | static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev, | 277 | static ssize_t kovaplus_sysfs_show_actual_profile(struct device *dev, |
265 | struct device_attribute *attr, char *buf) | 278 | struct device_attribute *attr, char *buf) |
266 | { | 279 | { |
@@ -310,6 +323,9 @@ static ssize_t kovaplus_sysfs_set_actual_profile(struct device *dev, | |||
310 | 323 | ||
311 | return size; | 324 | return size; |
312 | } | 325 | } |
326 | static DEVICE_ATTR(actual_profile, 0660, | ||
327 | kovaplus_sysfs_show_actual_profile, | ||
328 | kovaplus_sysfs_set_actual_profile); | ||
313 | 329 | ||
314 | static ssize_t kovaplus_sysfs_show_actual_cpi(struct device *dev, | 330 | static ssize_t kovaplus_sysfs_show_actual_cpi(struct device *dev, |
315 | struct device_attribute *attr, char *buf) | 331 | struct device_attribute *attr, char *buf) |
@@ -318,6 +334,7 @@ static ssize_t kovaplus_sysfs_show_actual_cpi(struct device *dev, | |||
318 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 334 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
319 | return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_cpi); | 335 | return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_cpi); |
320 | } | 336 | } |
337 | static DEVICE_ATTR(actual_cpi, 0440, kovaplus_sysfs_show_actual_cpi, NULL); | ||
321 | 338 | ||
322 | static ssize_t kovaplus_sysfs_show_actual_sensitivity_x(struct device *dev, | 339 | static ssize_t kovaplus_sysfs_show_actual_sensitivity_x(struct device *dev, |
323 | struct device_attribute *attr, char *buf) | 340 | struct device_attribute *attr, char *buf) |
@@ -326,6 +343,8 @@ static ssize_t kovaplus_sysfs_show_actual_sensitivity_x(struct device *dev, | |||
326 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 343 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
327 | return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_x_sensitivity); | 344 | return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_x_sensitivity); |
328 | } | 345 | } |
346 | static DEVICE_ATTR(actual_sensitivity_x, 0440, | ||
347 | kovaplus_sysfs_show_actual_sensitivity_x, NULL); | ||
329 | 348 | ||
330 | static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev, | 349 | static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev, |
331 | struct device_attribute *attr, char *buf) | 350 | struct device_attribute *attr, char *buf) |
@@ -334,6 +353,8 @@ static ssize_t kovaplus_sysfs_show_actual_sensitivity_y(struct device *dev, | |||
334 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 353 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
335 | return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_y_sensitivity); | 354 | return snprintf(buf, PAGE_SIZE, "%d\n", kovaplus->actual_y_sensitivity); |
336 | } | 355 | } |
356 | static DEVICE_ATTR(actual_sensitivity_y, 0440, | ||
357 | kovaplus_sysfs_show_actual_sensitivity_y, NULL); | ||
337 | 358 | ||
338 | static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev, | 359 | static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev, |
339 | struct device_attribute *attr, char *buf) | 360 | struct device_attribute *attr, char *buf) |
@@ -353,88 +374,44 @@ static ssize_t kovaplus_sysfs_show_firmware_version(struct device *dev, | |||
353 | 374 | ||
354 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); | 375 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); |
355 | } | 376 | } |
377 | static DEVICE_ATTR(firmware_version, 0440, | ||
378 | kovaplus_sysfs_show_firmware_version, NULL); | ||
379 | |||
380 | static struct attribute *kovaplus_attrs[] = { | ||
381 | &dev_attr_actual_cpi.attr, | ||
382 | &dev_attr_firmware_version.attr, | ||
383 | &dev_attr_actual_profile.attr, | ||
384 | &dev_attr_actual_sensitivity_x.attr, | ||
385 | &dev_attr_actual_sensitivity_y.attr, | ||
386 | NULL, | ||
387 | }; | ||
388 | |||
389 | static struct bin_attribute *kovaplus_bin_attributes[] = { | ||
390 | &bin_attr_control, | ||
391 | &bin_attr_info, | ||
392 | &bin_attr_profile_settings, | ||
393 | &bin_attr_profile_buttons, | ||
394 | &bin_attr_profile1_settings, | ||
395 | &bin_attr_profile2_settings, | ||
396 | &bin_attr_profile3_settings, | ||
397 | &bin_attr_profile4_settings, | ||
398 | &bin_attr_profile5_settings, | ||
399 | &bin_attr_profile1_buttons, | ||
400 | &bin_attr_profile2_buttons, | ||
401 | &bin_attr_profile3_buttons, | ||
402 | &bin_attr_profile4_buttons, | ||
403 | &bin_attr_profile5_buttons, | ||
404 | NULL, | ||
405 | }; | ||
356 | 406 | ||
357 | static struct device_attribute kovaplus_attributes[] = { | 407 | static const struct attribute_group kovaplus_group = { |
358 | __ATTR(actual_cpi, 0440, | 408 | .attrs = kovaplus_attrs, |
359 | kovaplus_sysfs_show_actual_cpi, NULL), | 409 | .bin_attrs = kovaplus_bin_attributes, |
360 | __ATTR(firmware_version, 0440, | ||
361 | kovaplus_sysfs_show_firmware_version, NULL), | ||
362 | __ATTR(actual_profile, 0660, | ||
363 | kovaplus_sysfs_show_actual_profile, | ||
364 | kovaplus_sysfs_set_actual_profile), | ||
365 | __ATTR(actual_sensitivity_x, 0440, | ||
366 | kovaplus_sysfs_show_actual_sensitivity_x, NULL), | ||
367 | __ATTR(actual_sensitivity_y, 0440, | ||
368 | kovaplus_sysfs_show_actual_sensitivity_y, NULL), | ||
369 | __ATTR_NULL | ||
370 | }; | 410 | }; |
371 | 411 | ||
372 | static struct bin_attribute kovaplus_bin_attributes[] = { | 412 | static const struct attribute_group *kovaplus_groups[] = { |
373 | KOVAPLUS_BIN_ATTRIBUTE_W(control, CONTROL), | 413 | &kovaplus_group, |
374 | KOVAPLUS_BIN_ATTRIBUTE_RW(info, INFO), | 414 | NULL, |
375 | KOVAPLUS_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), | ||
376 | KOVAPLUS_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), | ||
377 | { | ||
378 | .attr = { .name = "profile1_settings", .mode = 0440 }, | ||
379 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, | ||
380 | .read = kovaplus_sysfs_read_profilex_settings, | ||
381 | .private = &profile_numbers[0] | ||
382 | }, | ||
383 | { | ||
384 | .attr = { .name = "profile2_settings", .mode = 0440 }, | ||
385 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, | ||
386 | .read = kovaplus_sysfs_read_profilex_settings, | ||
387 | .private = &profile_numbers[1] | ||
388 | }, | ||
389 | { | ||
390 | .attr = { .name = "profile3_settings", .mode = 0440 }, | ||
391 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, | ||
392 | .read = kovaplus_sysfs_read_profilex_settings, | ||
393 | .private = &profile_numbers[2] | ||
394 | }, | ||
395 | { | ||
396 | .attr = { .name = "profile4_settings", .mode = 0440 }, | ||
397 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, | ||
398 | .read = kovaplus_sysfs_read_profilex_settings, | ||
399 | .private = &profile_numbers[3] | ||
400 | }, | ||
401 | { | ||
402 | .attr = { .name = "profile5_settings", .mode = 0440 }, | ||
403 | .size = KOVAPLUS_SIZE_PROFILE_SETTINGS, | ||
404 | .read = kovaplus_sysfs_read_profilex_settings, | ||
405 | .private = &profile_numbers[4] | ||
406 | }, | ||
407 | { | ||
408 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | ||
409 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, | ||
410 | .read = kovaplus_sysfs_read_profilex_buttons, | ||
411 | .private = &profile_numbers[0] | ||
412 | }, | ||
413 | { | ||
414 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | ||
415 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, | ||
416 | .read = kovaplus_sysfs_read_profilex_buttons, | ||
417 | .private = &profile_numbers[1] | ||
418 | }, | ||
419 | { | ||
420 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | ||
421 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, | ||
422 | .read = kovaplus_sysfs_read_profilex_buttons, | ||
423 | .private = &profile_numbers[2] | ||
424 | }, | ||
425 | { | ||
426 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | ||
427 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, | ||
428 | .read = kovaplus_sysfs_read_profilex_buttons, | ||
429 | .private = &profile_numbers[3] | ||
430 | }, | ||
431 | { | ||
432 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | ||
433 | .size = KOVAPLUS_SIZE_PROFILE_BUTTONS, | ||
434 | .read = kovaplus_sysfs_read_profilex_buttons, | ||
435 | .private = &profile_numbers[4] | ||
436 | }, | ||
437 | __ATTR_NULL | ||
438 | }; | 415 | }; |
439 | 416 | ||
440 | static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev, | 417 | static int kovaplus_init_kovaplus_device_struct(struct usb_device *usb_dev, |
@@ -662,8 +639,7 @@ static int __init kovaplus_init(void) | |||
662 | kovaplus_class = class_create(THIS_MODULE, "kovaplus"); | 639 | kovaplus_class = class_create(THIS_MODULE, "kovaplus"); |
663 | if (IS_ERR(kovaplus_class)) | 640 | if (IS_ERR(kovaplus_class)) |
664 | return PTR_ERR(kovaplus_class); | 641 | return PTR_ERR(kovaplus_class); |
665 | kovaplus_class->dev_attrs = kovaplus_attributes; | 642 | kovaplus_class->dev_groups = kovaplus_groups; |
666 | kovaplus_class->dev_bin_attrs = kovaplus_bin_attributes; | ||
667 | 643 | ||
668 | retval = hid_register_driver(&kovaplus_driver); | 644 | retval = hid_register_driver(&kovaplus_driver); |
669 | if (retval) | 645 | if (retval) |
diff --git a/drivers/hid/hid-roccat-pyra.c b/drivers/hid/hid-roccat-pyra.c index d4f1e3bee590..5a6dbbeee790 100644 --- a/drivers/hid/hid-roccat-pyra.c +++ b/drivers/hid/hid-roccat-pyra.c | |||
@@ -156,7 +156,8 @@ PYRA_SYSFS_W(thingy, THINGY) \ | |||
156 | PYRA_SYSFS_R(thingy, THINGY) | 156 | PYRA_SYSFS_R(thingy, THINGY) |
157 | 157 | ||
158 | #define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \ | 158 | #define PYRA_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
159 | { \ | 159 | PYRA_SYSFS_RW(thingy, THINGY); \ |
160 | static struct bin_attribute bin_attr_##thingy = { \ | ||
160 | .attr = { .name = #thingy, .mode = 0660 }, \ | 161 | .attr = { .name = #thingy, .mode = 0660 }, \ |
161 | .size = PYRA_SIZE_ ## THINGY, \ | 162 | .size = PYRA_SIZE_ ## THINGY, \ |
162 | .read = pyra_sysfs_read_ ## thingy, \ | 163 | .read = pyra_sysfs_read_ ## thingy, \ |
@@ -164,24 +165,25 @@ PYRA_SYSFS_R(thingy, THINGY) | |||
164 | } | 165 | } |
165 | 166 | ||
166 | #define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \ | 167 | #define PYRA_BIN_ATTRIBUTE_R(thingy, THINGY) \ |
167 | { \ | 168 | PYRA_SYSFS_R(thingy, THINGY); \ |
169 | static struct bin_attribute bin_attr_##thingy = { \ | ||
168 | .attr = { .name = #thingy, .mode = 0440 }, \ | 170 | .attr = { .name = #thingy, .mode = 0440 }, \ |
169 | .size = PYRA_SIZE_ ## THINGY, \ | 171 | .size = PYRA_SIZE_ ## THINGY, \ |
170 | .read = pyra_sysfs_read_ ## thingy, \ | 172 | .read = pyra_sysfs_read_ ## thingy, \ |
171 | } | 173 | } |
172 | 174 | ||
173 | #define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \ | 175 | #define PYRA_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
174 | { \ | 176 | PYRA_SYSFS_W(thingy, THINGY); \ |
177 | static struct bin_attribute bin_attr_##thingy = { \ | ||
175 | .attr = { .name = #thingy, .mode = 0220 }, \ | 178 | .attr = { .name = #thingy, .mode = 0220 }, \ |
176 | .size = PYRA_SIZE_ ## THINGY, \ | 179 | .size = PYRA_SIZE_ ## THINGY, \ |
177 | .write = pyra_sysfs_write_ ## thingy \ | 180 | .write = pyra_sysfs_write_ ## thingy \ |
178 | } | 181 | } |
179 | 182 | ||
180 | PYRA_SYSFS_W(control, CONTROL) | 183 | PYRA_BIN_ATTRIBUTE_W(control, CONTROL); |
181 | PYRA_SYSFS_RW(info, INFO) | 184 | PYRA_BIN_ATTRIBUTE_RW(info, INFO); |
182 | PYRA_SYSFS_RW(profile_settings, PROFILE_SETTINGS) | 185 | PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS); |
183 | PYRA_SYSFS_RW(profile_buttons, PROFILE_BUTTONS) | 186 | PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS); |
184 | PYRA_SYSFS_R(settings, SETTINGS) | ||
185 | 187 | ||
186 | static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, | 188 | static ssize_t pyra_sysfs_read_profilex_settings(struct file *fp, |
187 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 189 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
@@ -221,6 +223,25 @@ static ssize_t pyra_sysfs_read_profilex_buttons(struct file *fp, | |||
221 | PYRA_COMMAND_PROFILE_BUTTONS); | 223 | PYRA_COMMAND_PROFILE_BUTTONS); |
222 | } | 224 | } |
223 | 225 | ||
226 | #define PROFILE_ATTR(number) \ | ||
227 | static struct bin_attribute bin_attr_profile##number##_settings = { \ | ||
228 | .attr = { .name = "profile##number##_settings", .mode = 0440 }, \ | ||
229 | .size = PYRA_SIZE_PROFILE_SETTINGS, \ | ||
230 | .read = pyra_sysfs_read_profilex_settings, \ | ||
231 | .private = &profile_numbers[number-1], \ | ||
232 | }; \ | ||
233 | static struct bin_attribute bin_attr_profile##number##_buttons = { \ | ||
234 | .attr = { .name = "profile##number##_buttons", .mode = 0440 }, \ | ||
235 | .size = PYRA_SIZE_PROFILE_BUTTONS, \ | ||
236 | .read = pyra_sysfs_read_profilex_buttons, \ | ||
237 | .private = &profile_numbers[number-1], \ | ||
238 | }; | ||
239 | PROFILE_ATTR(1); | ||
240 | PROFILE_ATTR(2); | ||
241 | PROFILE_ATTR(3); | ||
242 | PROFILE_ATTR(4); | ||
243 | PROFILE_ATTR(5); | ||
244 | |||
224 | static ssize_t pyra_sysfs_write_settings(struct file *fp, | 245 | static ssize_t pyra_sysfs_write_settings(struct file *fp, |
225 | struct kobject *kobj, struct bin_attribute *attr, char *buf, | 246 | struct kobject *kobj, struct bin_attribute *attr, char *buf, |
226 | loff_t off, size_t count) | 247 | loff_t off, size_t count) |
@@ -258,6 +279,11 @@ static ssize_t pyra_sysfs_write_settings(struct file *fp, | |||
258 | return PYRA_SIZE_SETTINGS; | 279 | return PYRA_SIZE_SETTINGS; |
259 | } | 280 | } |
260 | 281 | ||
282 | PYRA_SYSFS_R(settings, SETTINGS); | ||
283 | static struct bin_attribute bin_attr_settings = | ||
284 | __BIN_ATTR(settings, (S_IWUSR | S_IRUGO), | ||
285 | pyra_sysfs_read_settings, pyra_sysfs_write_settings, | ||
286 | PYRA_SIZE_SETTINGS); | ||
261 | 287 | ||
262 | static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, | 288 | static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, |
263 | struct device_attribute *attr, char *buf) | 289 | struct device_attribute *attr, char *buf) |
@@ -266,6 +292,7 @@ static ssize_t pyra_sysfs_show_actual_cpi(struct device *dev, | |||
266 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); | 292 | hid_get_drvdata(dev_get_drvdata(dev->parent->parent)); |
267 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi); | 293 | return snprintf(buf, PAGE_SIZE, "%d\n", pyra->actual_cpi); |
268 | } | 294 | } |
295 | static DEVICE_ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL); | ||
269 | 296 | ||
270 | static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, | 297 | static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, |
271 | struct device_attribute *attr, char *buf) | 298 | struct device_attribute *attr, char *buf) |
@@ -282,6 +309,8 @@ static ssize_t pyra_sysfs_show_actual_profile(struct device *dev, | |||
282 | 309 | ||
283 | return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile); | 310 | return snprintf(buf, PAGE_SIZE, "%d\n", settings.startup_profile); |
284 | } | 311 | } |
312 | static DEVICE_ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL); | ||
313 | static DEVICE_ATTR(startup_profile, 0440, pyra_sysfs_show_actual_profile, NULL); | ||
285 | 314 | ||
286 | static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, | 315 | static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, |
287 | struct device_attribute *attr, char *buf) | 316 | struct device_attribute *attr, char *buf) |
@@ -301,84 +330,44 @@ static ssize_t pyra_sysfs_show_firmware_version(struct device *dev, | |||
301 | 330 | ||
302 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); | 331 | return snprintf(buf, PAGE_SIZE, "%d\n", info.firmware_version); |
303 | } | 332 | } |
333 | static DEVICE_ATTR(firmware_version, 0440, pyra_sysfs_show_firmware_version, | ||
334 | NULL); | ||
335 | |||
336 | static struct attribute *pyra_attrs[] = { | ||
337 | &dev_attr_actual_cpi.attr, | ||
338 | &dev_attr_actual_profile.attr, | ||
339 | &dev_attr_firmware_version.attr, | ||
340 | &dev_attr_startup_profile.attr, | ||
341 | NULL, | ||
342 | }; | ||
343 | |||
344 | static struct bin_attribute *pyra_bin_attributes[] = { | ||
345 | &bin_attr_control, | ||
346 | &bin_attr_info, | ||
347 | &bin_attr_profile_settings, | ||
348 | &bin_attr_profile_buttons, | ||
349 | &bin_attr_settings, | ||
350 | &bin_attr_profile1_settings, | ||
351 | &bin_attr_profile2_settings, | ||
352 | &bin_attr_profile3_settings, | ||
353 | &bin_attr_profile4_settings, | ||
354 | &bin_attr_profile5_settings, | ||
355 | &bin_attr_profile1_buttons, | ||
356 | &bin_attr_profile2_buttons, | ||
357 | &bin_attr_profile3_buttons, | ||
358 | &bin_attr_profile4_buttons, | ||
359 | &bin_attr_profile5_buttons, | ||
360 | NULL, | ||
361 | }; | ||
304 | 362 | ||
305 | static struct device_attribute pyra_attributes[] = { | 363 | static const struct attribute_group pyra_group = { |
306 | __ATTR(actual_cpi, 0440, pyra_sysfs_show_actual_cpi, NULL), | 364 | .attrs = pyra_attrs, |
307 | __ATTR(actual_profile, 0440, pyra_sysfs_show_actual_profile, NULL), | 365 | .bin_attrs = pyra_bin_attributes, |
308 | __ATTR(firmware_version, 0440, | ||
309 | pyra_sysfs_show_firmware_version, NULL), | ||
310 | __ATTR(startup_profile, 0440, | ||
311 | pyra_sysfs_show_actual_profile, NULL), | ||
312 | __ATTR_NULL | ||
313 | }; | 366 | }; |
314 | 367 | ||
315 | static struct bin_attribute pyra_bin_attributes[] = { | 368 | static const struct attribute_group *pyra_groups[] = { |
316 | PYRA_BIN_ATTRIBUTE_W(control, CONTROL), | 369 | &pyra_group, |
317 | PYRA_BIN_ATTRIBUTE_RW(info, INFO), | 370 | NULL, |
318 | PYRA_BIN_ATTRIBUTE_RW(profile_settings, PROFILE_SETTINGS), | ||
319 | PYRA_BIN_ATTRIBUTE_RW(profile_buttons, PROFILE_BUTTONS), | ||
320 | PYRA_BIN_ATTRIBUTE_RW(settings, SETTINGS), | ||
321 | { | ||
322 | .attr = { .name = "profile1_settings", .mode = 0440 }, | ||
323 | .size = PYRA_SIZE_PROFILE_SETTINGS, | ||
324 | .read = pyra_sysfs_read_profilex_settings, | ||
325 | .private = &profile_numbers[0] | ||
326 | }, | ||
327 | { | ||
328 | .attr = { .name = "profile2_settings", .mode = 0440 }, | ||
329 | .size = PYRA_SIZE_PROFILE_SETTINGS, | ||
330 | .read = pyra_sysfs_read_profilex_settings, | ||
331 | .private = &profile_numbers[1] | ||
332 | }, | ||
333 | { | ||
334 | .attr = { .name = "profile3_settings", .mode = 0440 }, | ||
335 | .size = PYRA_SIZE_PROFILE_SETTINGS, | ||
336 | .read = pyra_sysfs_read_profilex_settings, | ||
337 | .private = &profile_numbers[2] | ||
338 | }, | ||
339 | { | ||
340 | .attr = { .name = "profile4_settings", .mode = 0440 }, | ||
341 | .size = PYRA_SIZE_PROFILE_SETTINGS, | ||
342 | .read = pyra_sysfs_read_profilex_settings, | ||
343 | .private = &profile_numbers[3] | ||
344 | }, | ||
345 | { | ||
346 | .attr = { .name = "profile5_settings", .mode = 0440 }, | ||
347 | .size = PYRA_SIZE_PROFILE_SETTINGS, | ||
348 | .read = pyra_sysfs_read_profilex_settings, | ||
349 | .private = &profile_numbers[4] | ||
350 | }, | ||
351 | { | ||
352 | .attr = { .name = "profile1_buttons", .mode = 0440 }, | ||
353 | .size = PYRA_SIZE_PROFILE_BUTTONS, | ||
354 | .read = pyra_sysfs_read_profilex_buttons, | ||
355 | .private = &profile_numbers[0] | ||
356 | }, | ||
357 | { | ||
358 | .attr = { .name = "profile2_buttons", .mode = 0440 }, | ||
359 | .size = PYRA_SIZE_PROFILE_BUTTONS, | ||
360 | .read = pyra_sysfs_read_profilex_buttons, | ||
361 | .private = &profile_numbers[1] | ||
362 | }, | ||
363 | { | ||
364 | .attr = { .name = "profile3_buttons", .mode = 0440 }, | ||
365 | .size = PYRA_SIZE_PROFILE_BUTTONS, | ||
366 | .read = pyra_sysfs_read_profilex_buttons, | ||
367 | .private = &profile_numbers[2] | ||
368 | }, | ||
369 | { | ||
370 | .attr = { .name = "profile4_buttons", .mode = 0440 }, | ||
371 | .size = PYRA_SIZE_PROFILE_BUTTONS, | ||
372 | .read = pyra_sysfs_read_profilex_buttons, | ||
373 | .private = &profile_numbers[3] | ||
374 | }, | ||
375 | { | ||
376 | .attr = { .name = "profile5_buttons", .mode = 0440 }, | ||
377 | .size = PYRA_SIZE_PROFILE_BUTTONS, | ||
378 | .read = pyra_sysfs_read_profilex_buttons, | ||
379 | .private = &profile_numbers[4] | ||
380 | }, | ||
381 | __ATTR_NULL | ||
382 | }; | 371 | }; |
383 | 372 | ||
384 | static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, | 373 | static int pyra_init_pyra_device_struct(struct usb_device *usb_dev, |
@@ -600,8 +589,7 @@ static int __init pyra_init(void) | |||
600 | pyra_class = class_create(THIS_MODULE, "pyra"); | 589 | pyra_class = class_create(THIS_MODULE, "pyra"); |
601 | if (IS_ERR(pyra_class)) | 590 | if (IS_ERR(pyra_class)) |
602 | return PTR_ERR(pyra_class); | 591 | return PTR_ERR(pyra_class); |
603 | pyra_class->dev_attrs = pyra_attributes; | 592 | pyra_class->dev_groups = pyra_groups; |
604 | pyra_class->dev_bin_attrs = pyra_bin_attributes; | ||
605 | 593 | ||
606 | retval = hid_register_driver(&pyra_driver); | 594 | retval = hid_register_driver(&pyra_driver); |
607 | if (retval) | 595 | if (retval) |
diff --git a/drivers/hid/hid-roccat-savu.c b/drivers/hid/hid-roccat-savu.c index 31747a29c093..0332267199d5 100644 --- a/drivers/hid/hid-roccat-savu.c +++ b/drivers/hid/hid-roccat-savu.c | |||
@@ -94,44 +94,48 @@ SAVU_SYSFS_W(thingy, THINGY) \ | |||
94 | SAVU_SYSFS_R(thingy, THINGY) | 94 | SAVU_SYSFS_R(thingy, THINGY) |
95 | 95 | ||
96 | #define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \ | 96 | #define SAVU_BIN_ATTRIBUTE_RW(thingy, THINGY) \ |
97 | { \ | 97 | SAVU_SYSFS_RW(thingy, THINGY); \ |
98 | static struct bin_attribute bin_attr_##thingy = { \ | ||
98 | .attr = { .name = #thingy, .mode = 0660 }, \ | 99 | .attr = { .name = #thingy, .mode = 0660 }, \ |
99 | .size = SAVU_SIZE_ ## THINGY, \ | 100 | .size = SAVU_SIZE_ ## THINGY, \ |
100 | .read = savu_sysfs_read_ ## thingy, \ | 101 | .read = savu_sysfs_read_ ## thingy, \ |
101 | .write = savu_sysfs_write_ ## thingy \ | 102 | .write = savu_sysfs_write_ ## thingy \ |
102 | } | 103 | } |
103 | 104 | ||
104 | #define SAVU_BIN_ATTRIBUTE_R(thingy, THINGY) \ | ||
105 | { \ | ||
106 | .attr = { .name = #thingy, .mode = 0440 }, \ | ||
107 | .size = SAVU_SIZE_ ## THINGY, \ | ||
108 | .read = savu_sysfs_read_ ## thingy, \ | ||
109 | } | ||
110 | |||
111 | #define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \ | 105 | #define SAVU_BIN_ATTRIBUTE_W(thingy, THINGY) \ |
112 | { \ | 106 | SAVU_SYSFS_W(thingy, THINGY); \ |
107 | static struct bin_attribute bin_attr_##thingy = { \ | ||
113 | .attr = { .name = #thingy, .mode = 0220 }, \ | 108 | .attr = { .name = #thingy, .mode = 0220 }, \ |
114 | .size = SAVU_SIZE_ ## THINGY, \ | 109 | .size = SAVU_SIZE_ ## THINGY, \ |
115 | .write = savu_sysfs_write_ ## thingy \ | 110 | .write = savu_sysfs_write_ ## thingy \ |
116 | } | 111 | } |
117 | 112 | ||
118 | SAVU_SYSFS_W(control, CONTROL) | 113 | SAVU_BIN_ATTRIBUTE_W(control, CONTROL); |
119 | SAVU_SYSFS_RW(profile, PROFILE) | 114 | SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE); |
120 | SAVU_SYSFS_RW(general, GENERAL) | 115 | SAVU_BIN_ATTRIBUTE_RW(general, GENERAL); |
121 | SAVU_SYSFS_RW(buttons, BUTTONS) | 116 | SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS); |
122 | SAVU_SYSFS_RW(macro, MACRO) | 117 | SAVU_BIN_ATTRIBUTE_RW(macro, MACRO); |
123 | SAVU_SYSFS_RW(info, INFO) | 118 | SAVU_BIN_ATTRIBUTE_RW(info, INFO); |
124 | SAVU_SYSFS_RW(sensor, SENSOR) | 119 | SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR); |
125 | 120 | ||
126 | static struct bin_attribute savu_bin_attributes[] = { | 121 | static struct bin_attribute *savu_bin_attributes[] = { |
127 | SAVU_BIN_ATTRIBUTE_W(control, CONTROL), | 122 | &bin_attr_control, |
128 | SAVU_BIN_ATTRIBUTE_RW(profile, PROFILE), | 123 | &bin_attr_profile, |
129 | SAVU_BIN_ATTRIBUTE_RW(general, GENERAL), | 124 | &bin_attr_general, |
130 | SAVU_BIN_ATTRIBUTE_RW(buttons, BUTTONS), | 125 | &bin_attr_buttons, |
131 | SAVU_BIN_ATTRIBUTE_RW(macro, MACRO), | 126 | &bin_attr_macro, |
132 | SAVU_BIN_ATTRIBUTE_RW(info, INFO), | 127 | &bin_attr_info, |
133 | SAVU_BIN_ATTRIBUTE_RW(sensor, SENSOR), | 128 | &bin_attr_sensor, |
134 | __ATTR_NULL | 129 | NULL, |
130 | }; | ||
131 | |||
132 | static const struct attribute_group savu_group = { | ||
133 | .bin_attrs = savu_bin_attributes, | ||
134 | }; | ||
135 | |||
136 | static const struct attribute_group *savu_groups[] = { | ||
137 | &savu_group, | ||
138 | NULL, | ||
135 | }; | 139 | }; |
136 | 140 | ||
137 | static int savu_init_savu_device_struct(struct usb_device *usb_dev, | 141 | static int savu_init_savu_device_struct(struct usb_device *usb_dev, |
@@ -294,7 +298,7 @@ static int __init savu_init(void) | |||
294 | savu_class = class_create(THIS_MODULE, "savu"); | 298 | savu_class = class_create(THIS_MODULE, "savu"); |
295 | if (IS_ERR(savu_class)) | 299 | if (IS_ERR(savu_class)) |
296 | return PTR_ERR(savu_class); | 300 | return PTR_ERR(savu_class); |
297 | savu_class->dev_bin_attrs = savu_bin_attributes; | 301 | savu_class->dev_groups = savu_groups; |
298 | 302 | ||
299 | retval = hid_register_driver(&savu_driver); | 303 | retval = hid_register_driver(&savu_driver); |
300 | if (retval) | 304 | if (retval) |
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c index da739d9d1905..922a7fea2ce6 100644 --- a/drivers/input/gameport/gameport.c +++ b/drivers/input/gameport/gameport.c | |||
@@ -639,16 +639,18 @@ EXPORT_SYMBOL(gameport_unregister_port); | |||
639 | * Gameport driver operations | 639 | * Gameport driver operations |
640 | */ | 640 | */ |
641 | 641 | ||
642 | static ssize_t gameport_driver_show_description(struct device_driver *drv, char *buf) | 642 | static ssize_t description_show(struct device_driver *drv, char *buf) |
643 | { | 643 | { |
644 | struct gameport_driver *driver = to_gameport_driver(drv); | 644 | struct gameport_driver *driver = to_gameport_driver(drv); |
645 | return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); | 645 | return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); |
646 | } | 646 | } |
647 | static DRIVER_ATTR_RO(description); | ||
647 | 648 | ||
648 | static struct driver_attribute gameport_driver_attrs[] = { | 649 | static struct attribute *gameport_driver_attrs[] = { |
649 | __ATTR(description, S_IRUGO, gameport_driver_show_description, NULL), | 650 | &driver_attr_description.attr, |
650 | __ATTR_NULL | 651 | NULL |
651 | }; | 652 | }; |
653 | ATTRIBUTE_GROUPS(gameport_driver); | ||
652 | 654 | ||
653 | static int gameport_driver_probe(struct device *dev) | 655 | static int gameport_driver_probe(struct device *dev) |
654 | { | 656 | { |
@@ -749,7 +751,7 @@ static int gameport_bus_match(struct device *dev, struct device_driver *drv) | |||
749 | static struct bus_type gameport_bus = { | 751 | static struct bus_type gameport_bus = { |
750 | .name = "gameport", | 752 | .name = "gameport", |
751 | .dev_attrs = gameport_device_attrs, | 753 | .dev_attrs = gameport_device_attrs, |
752 | .drv_attrs = gameport_driver_attrs, | 754 | .drv_groups = gameport_driver_groups, |
753 | .match = gameport_bus_match, | 755 | .match = gameport_bus_match, |
754 | .probe = gameport_driver_probe, | 756 | .probe = gameport_driver_probe, |
755 | .remove = gameport_driver_remove, | 757 | .remove = gameport_driver_remove, |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 25fc5971f426..2b56855c2c77 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -732,19 +732,20 @@ EXPORT_SYMBOL(serio_unregister_child_port); | |||
732 | * Serio driver operations | 732 | * Serio driver operations |
733 | */ | 733 | */ |
734 | 734 | ||
735 | static ssize_t serio_driver_show_description(struct device_driver *drv, char *buf) | 735 | static ssize_t description_show(struct device_driver *drv, char *buf) |
736 | { | 736 | { |
737 | struct serio_driver *driver = to_serio_driver(drv); | 737 | struct serio_driver *driver = to_serio_driver(drv); |
738 | return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); | 738 | return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); |
739 | } | 739 | } |
740 | static DRIVER_ATTR_RO(description); | ||
740 | 741 | ||
741 | static ssize_t serio_driver_show_bind_mode(struct device_driver *drv, char *buf) | 742 | static ssize_t bind_mode_show(struct device_driver *drv, char *buf) |
742 | { | 743 | { |
743 | struct serio_driver *serio_drv = to_serio_driver(drv); | 744 | struct serio_driver *serio_drv = to_serio_driver(drv); |
744 | return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto"); | 745 | return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto"); |
745 | } | 746 | } |
746 | 747 | ||
747 | static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char *buf, size_t count) | 748 | static ssize_t bind_mode_store(struct device_driver *drv, const char *buf, size_t count) |
748 | { | 749 | { |
749 | struct serio_driver *serio_drv = to_serio_driver(drv); | 750 | struct serio_driver *serio_drv = to_serio_driver(drv); |
750 | int retval; | 751 | int retval; |
@@ -760,14 +761,14 @@ static ssize_t serio_driver_set_bind_mode(struct device_driver *drv, const char | |||
760 | 761 | ||
761 | return retval; | 762 | return retval; |
762 | } | 763 | } |
764 | static DRIVER_ATTR_RW(bind_mode); | ||
763 | 765 | ||
764 | 766 | static struct attribute *serio_driver_attrs[] = { | |
765 | static struct driver_attribute serio_driver_attrs[] = { | 767 | &driver_attr_description.attr, |
766 | __ATTR(description, S_IRUGO, serio_driver_show_description, NULL), | 768 | &driver_attr_bind_mode.attr, |
767 | __ATTR(bind_mode, S_IWUSR | S_IRUGO, | 769 | NULL, |
768 | serio_driver_show_bind_mode, serio_driver_set_bind_mode), | ||
769 | __ATTR_NULL | ||
770 | }; | 770 | }; |
771 | ATTRIBUTE_GROUPS(serio_driver); | ||
771 | 772 | ||
772 | static int serio_driver_probe(struct device *dev) | 773 | static int serio_driver_probe(struct device *dev) |
773 | { | 774 | { |
@@ -996,7 +997,7 @@ EXPORT_SYMBOL(serio_interrupt); | |||
996 | static struct bus_type serio_bus = { | 997 | static struct bus_type serio_bus = { |
997 | .name = "serio", | 998 | .name = "serio", |
998 | .dev_attrs = serio_device_attrs, | 999 | .dev_attrs = serio_device_attrs, |
999 | .drv_attrs = serio_driver_attrs, | 1000 | .drv_groups = serio_driver_groups, |
1000 | .match = serio_bus_match, | 1001 | .match = serio_bus_match, |
1001 | .uevent = serio_uevent, | 1002 | .uevent = serio_uevent, |
1002 | .probe = serio_driver_probe, | 1003 | .probe = serio_driver_probe, |
diff --git a/drivers/isdn/mISDN/core.c b/drivers/isdn/mISDN/core.c index da30c5cb9609..faf505462a4f 100644 --- a/drivers/isdn/mISDN/core.c +++ b/drivers/isdn/mISDN/core.c | |||
@@ -37,8 +37,8 @@ static void mISDN_dev_release(struct device *dev) | |||
37 | /* nothing to do: the device is part of its parent's data structure */ | 37 | /* nothing to do: the device is part of its parent's data structure */ |
38 | } | 38 | } |
39 | 39 | ||
40 | static ssize_t _show_id(struct device *dev, | 40 | static ssize_t id_show(struct device *dev, |
41 | struct device_attribute *attr, char *buf) | 41 | struct device_attribute *attr, char *buf) |
42 | { | 42 | { |
43 | struct mISDNdevice *mdev = dev_to_mISDN(dev); | 43 | struct mISDNdevice *mdev = dev_to_mISDN(dev); |
44 | 44 | ||
@@ -46,9 +46,10 @@ static ssize_t _show_id(struct device *dev, | |||
46 | return -ENODEV; | 46 | return -ENODEV; |
47 | return sprintf(buf, "%d\n", mdev->id); | 47 | return sprintf(buf, "%d\n", mdev->id); |
48 | } | 48 | } |
49 | static DEVICE_ATTR_RO(id); | ||
49 | 50 | ||
50 | static ssize_t _show_nrbchan(struct device *dev, | 51 | static ssize_t nrbchan_show(struct device *dev, |
51 | struct device_attribute *attr, char *buf) | 52 | struct device_attribute *attr, char *buf) |
52 | { | 53 | { |
53 | struct mISDNdevice *mdev = dev_to_mISDN(dev); | 54 | struct mISDNdevice *mdev = dev_to_mISDN(dev); |
54 | 55 | ||
@@ -56,9 +57,10 @@ static ssize_t _show_nrbchan(struct device *dev, | |||
56 | return -ENODEV; | 57 | return -ENODEV; |
57 | return sprintf(buf, "%d\n", mdev->nrbchan); | 58 | return sprintf(buf, "%d\n", mdev->nrbchan); |
58 | } | 59 | } |
60 | static DEVICE_ATTR_RO(nrbchan); | ||
59 | 61 | ||
60 | static ssize_t _show_d_protocols(struct device *dev, | 62 | static ssize_t d_protocols_show(struct device *dev, |
61 | struct device_attribute *attr, char *buf) | 63 | struct device_attribute *attr, char *buf) |
62 | { | 64 | { |
63 | struct mISDNdevice *mdev = dev_to_mISDN(dev); | 65 | struct mISDNdevice *mdev = dev_to_mISDN(dev); |
64 | 66 | ||
@@ -66,9 +68,10 @@ static ssize_t _show_d_protocols(struct device *dev, | |||
66 | return -ENODEV; | 68 | return -ENODEV; |
67 | return sprintf(buf, "%d\n", mdev->Dprotocols); | 69 | return sprintf(buf, "%d\n", mdev->Dprotocols); |
68 | } | 70 | } |
71 | static DEVICE_ATTR_RO(d_protocols); | ||
69 | 72 | ||
70 | static ssize_t _show_b_protocols(struct device *dev, | 73 | static ssize_t b_protocols_show(struct device *dev, |
71 | struct device_attribute *attr, char *buf) | 74 | struct device_attribute *attr, char *buf) |
72 | { | 75 | { |
73 | struct mISDNdevice *mdev = dev_to_mISDN(dev); | 76 | struct mISDNdevice *mdev = dev_to_mISDN(dev); |
74 | 77 | ||
@@ -76,9 +79,10 @@ static ssize_t _show_b_protocols(struct device *dev, | |||
76 | return -ENODEV; | 79 | return -ENODEV; |
77 | return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols()); | 80 | return sprintf(buf, "%d\n", mdev->Bprotocols | get_all_Bprotocols()); |
78 | } | 81 | } |
82 | static DEVICE_ATTR_RO(b_protocols); | ||
79 | 83 | ||
80 | static ssize_t _show_protocol(struct device *dev, | 84 | static ssize_t protocol_show(struct device *dev, |
81 | struct device_attribute *attr, char *buf) | 85 | struct device_attribute *attr, char *buf) |
82 | { | 86 | { |
83 | struct mISDNdevice *mdev = dev_to_mISDN(dev); | 87 | struct mISDNdevice *mdev = dev_to_mISDN(dev); |
84 | 88 | ||
@@ -86,17 +90,19 @@ static ssize_t _show_protocol(struct device *dev, | |||
86 | return -ENODEV; | 90 | return -ENODEV; |
87 | return sprintf(buf, "%d\n", mdev->D.protocol); | 91 | return sprintf(buf, "%d\n", mdev->D.protocol); |
88 | } | 92 | } |
93 | static DEVICE_ATTR_RO(protocol); | ||
89 | 94 | ||
90 | static ssize_t _show_name(struct device *dev, | 95 | static ssize_t name_show(struct device *dev, |
91 | struct device_attribute *attr, char *buf) | 96 | struct device_attribute *attr, char *buf) |
92 | { | 97 | { |
93 | strcpy(buf, dev_name(dev)); | 98 | strcpy(buf, dev_name(dev)); |
94 | return strlen(buf); | 99 | return strlen(buf); |
95 | } | 100 | } |
101 | static DEVICE_ATTR_RO(name); | ||
96 | 102 | ||
97 | #if 0 /* hangs */ | 103 | #if 0 /* hangs */ |
98 | static ssize_t _set_name(struct device *dev, struct device_attribute *attr, | 104 | static ssize_t name_set(struct device *dev, struct device_attribute *attr, |
99 | const char *buf, size_t count) | 105 | const char *buf, size_t count) |
100 | { | 106 | { |
101 | int err = 0; | 107 | int err = 0; |
102 | char *out = kmalloc(count + 1, GFP_KERNEL); | 108 | char *out = kmalloc(count + 1, GFP_KERNEL); |
@@ -113,10 +119,11 @@ static ssize_t _set_name(struct device *dev, struct device_attribute *attr, | |||
113 | 119 | ||
114 | return (err < 0) ? err : count; | 120 | return (err < 0) ? err : count; |
115 | } | 121 | } |
122 | static DEVICE_ATTR_RW(name); | ||
116 | #endif | 123 | #endif |
117 | 124 | ||
118 | static ssize_t _show_channelmap(struct device *dev, | 125 | static ssize_t channelmap_show(struct device *dev, |
119 | struct device_attribute *attr, char *buf) | 126 | struct device_attribute *attr, char *buf) |
120 | { | 127 | { |
121 | struct mISDNdevice *mdev = dev_to_mISDN(dev); | 128 | struct mISDNdevice *mdev = dev_to_mISDN(dev); |
122 | char *bp = buf; | 129 | char *bp = buf; |
@@ -127,18 +134,19 @@ static ssize_t _show_channelmap(struct device *dev, | |||
127 | 134 | ||
128 | return bp - buf; | 135 | return bp - buf; |
129 | } | 136 | } |
130 | 137 | static DEVICE_ATTR_RO(channelmap); | |
131 | static struct device_attribute mISDN_dev_attrs[] = { | 138 | |
132 | __ATTR(id, S_IRUGO, _show_id, NULL), | 139 | static struct attribute *mISDN_attrs[] = { |
133 | __ATTR(d_protocols, S_IRUGO, _show_d_protocols, NULL), | 140 | &dev_attr_id.attr, |
134 | __ATTR(b_protocols, S_IRUGO, _show_b_protocols, NULL), | 141 | &dev_attr_d_protocols.attr, |
135 | __ATTR(protocol, S_IRUGO, _show_protocol, NULL), | 142 | &dev_attr_b_protocols.attr, |
136 | __ATTR(channelmap, S_IRUGO, _show_channelmap, NULL), | 143 | &dev_attr_protocol.attr, |
137 | __ATTR(nrbchan, S_IRUGO, _show_nrbchan, NULL), | 144 | &dev_attr_channelmap.attr, |
138 | __ATTR(name, S_IRUGO, _show_name, NULL), | 145 | &dev_attr_nrbchan.attr, |
139 | /* __ATTR(name, S_IRUGO | S_IWUSR, _show_name, _set_name), */ | 146 | &dev_attr_name.attr, |
140 | {} | 147 | NULL, |
141 | }; | 148 | }; |
149 | ATTRIBUTE_GROUPS(mISDN); | ||
142 | 150 | ||
143 | static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env) | 151 | static int mISDN_uevent(struct device *dev, struct kobj_uevent_env *env) |
144 | { | 152 | { |
@@ -162,7 +170,7 @@ static struct class mISDN_class = { | |||
162 | .name = "mISDN", | 170 | .name = "mISDN", |
163 | .owner = THIS_MODULE, | 171 | .owner = THIS_MODULE, |
164 | .dev_uevent = mISDN_uevent, | 172 | .dev_uevent = mISDN_uevent, |
165 | .dev_attrs = mISDN_dev_attrs, | 173 | .dev_groups = mISDN_groups, |
166 | .dev_release = mISDN_dev_release, | 174 | .dev_release = mISDN_dev_release, |
167 | .class_release = mISDN_class_release, | 175 | .class_release = mISDN_class_release, |
168 | }; | 176 | }; |
diff --git a/drivers/leds/led-class.c b/drivers/leds/led-class.c index 4336e37a97f4..f37d63cf726b 100644 --- a/drivers/leds/led-class.c +++ b/drivers/leds/led-class.c | |||
@@ -29,7 +29,7 @@ static void led_update_brightness(struct led_classdev *led_cdev) | |||
29 | led_cdev->brightness = led_cdev->brightness_get(led_cdev); | 29 | led_cdev->brightness = led_cdev->brightness_get(led_cdev); |
30 | } | 30 | } |
31 | 31 | ||
32 | static ssize_t led_brightness_show(struct device *dev, | 32 | static ssize_t brightness_show(struct device *dev, |
33 | struct device_attribute *attr, char *buf) | 33 | struct device_attribute *attr, char *buf) |
34 | { | 34 | { |
35 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 35 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
@@ -40,7 +40,7 @@ static ssize_t led_brightness_show(struct device *dev, | |||
40 | return sprintf(buf, "%u\n", led_cdev->brightness); | 40 | return sprintf(buf, "%u\n", led_cdev->brightness); |
41 | } | 41 | } |
42 | 42 | ||
43 | static ssize_t led_brightness_store(struct device *dev, | 43 | static ssize_t brightness_store(struct device *dev, |
44 | struct device_attribute *attr, const char *buf, size_t size) | 44 | struct device_attribute *attr, const char *buf, size_t size) |
45 | { | 45 | { |
46 | struct led_classdev *led_cdev = dev_get_drvdata(dev); | 46 | struct led_classdev *led_cdev = dev_get_drvdata(dev); |
@@ -57,6 +57,7 @@ static ssize_t led_brightness_store(struct device *dev, | |||
57 | 57 | ||
58 | return size; | 58 | return size; |
59 | } | 59 | } |
60 | static DEVICE_ATTR_RW(brightness); | ||
60 | 61 | ||
61 | static ssize_t led_max_brightness_show(struct device *dev, | 62 | static ssize_t led_max_brightness_show(struct device *dev, |
62 | struct device_attribute *attr, char *buf) | 63 | struct device_attribute *attr, char *buf) |
@@ -65,14 +66,35 @@ static ssize_t led_max_brightness_show(struct device *dev, | |||
65 | 66 | ||
66 | return sprintf(buf, "%u\n", led_cdev->max_brightness); | 67 | return sprintf(buf, "%u\n", led_cdev->max_brightness); |
67 | } | 68 | } |
69 | static DEVICE_ATTR(max_brightness, 0444, led_max_brightness_show, NULL); | ||
68 | 70 | ||
69 | static struct device_attribute led_class_attrs[] = { | ||
70 | __ATTR(brightness, 0644, led_brightness_show, led_brightness_store), | ||
71 | __ATTR(max_brightness, 0444, led_max_brightness_show, NULL), | ||
72 | #ifdef CONFIG_LEDS_TRIGGERS | 71 | #ifdef CONFIG_LEDS_TRIGGERS |
73 | __ATTR(trigger, 0644, led_trigger_show, led_trigger_store), | 72 | static DEVICE_ATTR(trigger, 0644, led_trigger_show, led_trigger_store); |
73 | static struct attribute *led_trigger_attrs[] = { | ||
74 | &dev_attr_trigger.attr, | ||
75 | NULL, | ||
76 | }; | ||
77 | static const struct attribute_group led_trigger_group = { | ||
78 | .attrs = led_trigger_attrs, | ||
79 | }; | ||
80 | #endif | ||
81 | |||
82 | static struct attribute *led_class_attrs[] = { | ||
83 | &dev_attr_brightness.attr, | ||
84 | &dev_attr_max_brightness.attr, | ||
85 | NULL, | ||
86 | }; | ||
87 | |||
88 | static const struct attribute_group led_group = { | ||
89 | .attrs = led_class_attrs, | ||
90 | }; | ||
91 | |||
92 | static const struct attribute_group *led_groups[] = { | ||
93 | &led_group, | ||
94 | #ifdef CONFIG_LEDS_TRIGGERS | ||
95 | &led_trigger_group, | ||
74 | #endif | 96 | #endif |
75 | __ATTR_NULL, | 97 | NULL, |
76 | }; | 98 | }; |
77 | 99 | ||
78 | static void led_timer_function(unsigned long data) | 100 | static void led_timer_function(unsigned long data) |
@@ -258,7 +280,7 @@ static int __init leds_init(void) | |||
258 | if (IS_ERR(leds_class)) | 280 | if (IS_ERR(leds_class)) |
259 | return PTR_ERR(leds_class); | 281 | return PTR_ERR(leds_class); |
260 | leds_class->pm = &leds_class_dev_pm_ops; | 282 | leds_class->pm = &leds_class_dev_pm_ops; |
261 | leds_class->dev_attrs = led_class_attrs; | 283 | leds_class->dev_groups = led_groups; |
262 | return 0; | 284 | return 0; |
263 | } | 285 | } |
264 | 286 | ||
diff --git a/drivers/media/v4l2-core/v4l2-dev.c b/drivers/media/v4l2-core/v4l2-dev.c index c8859d6ff6ad..b0f49b014bc5 100644 --- a/drivers/media/v4l2-core/v4l2-dev.c +++ b/drivers/media/v4l2-core/v4l2-dev.c | |||
@@ -38,24 +38,25 @@ | |||
38 | * sysfs stuff | 38 | * sysfs stuff |
39 | */ | 39 | */ |
40 | 40 | ||
41 | static ssize_t show_index(struct device *cd, | 41 | static ssize_t index_show(struct device *cd, |
42 | struct device_attribute *attr, char *buf) | 42 | struct device_attribute *attr, char *buf) |
43 | { | 43 | { |
44 | struct video_device *vdev = to_video_device(cd); | 44 | struct video_device *vdev = to_video_device(cd); |
45 | 45 | ||
46 | return sprintf(buf, "%i\n", vdev->index); | 46 | return sprintf(buf, "%i\n", vdev->index); |
47 | } | 47 | } |
48 | static DEVICE_ATTR_RO(index); | ||
48 | 49 | ||
49 | static ssize_t show_debug(struct device *cd, | 50 | static ssize_t debug_show(struct device *cd, |
50 | struct device_attribute *attr, char *buf) | 51 | struct device_attribute *attr, char *buf) |
51 | { | 52 | { |
52 | struct video_device *vdev = to_video_device(cd); | 53 | struct video_device *vdev = to_video_device(cd); |
53 | 54 | ||
54 | return sprintf(buf, "%i\n", vdev->debug); | 55 | return sprintf(buf, "%i\n", vdev->debug); |
55 | } | 56 | } |
56 | 57 | ||
57 | static ssize_t set_debug(struct device *cd, struct device_attribute *attr, | 58 | static ssize_t debug_store(struct device *cd, struct device_attribute *attr, |
58 | const char *buf, size_t len) | 59 | const char *buf, size_t len) |
59 | { | 60 | { |
60 | struct video_device *vdev = to_video_device(cd); | 61 | struct video_device *vdev = to_video_device(cd); |
61 | int res = 0; | 62 | int res = 0; |
@@ -68,21 +69,24 @@ static ssize_t set_debug(struct device *cd, struct device_attribute *attr, | |||
68 | vdev->debug = value; | 69 | vdev->debug = value; |
69 | return len; | 70 | return len; |
70 | } | 71 | } |
72 | static DEVICE_ATTR_RW(debug); | ||
71 | 73 | ||
72 | static ssize_t show_name(struct device *cd, | 74 | static ssize_t name_show(struct device *cd, |
73 | struct device_attribute *attr, char *buf) | 75 | struct device_attribute *attr, char *buf) |
74 | { | 76 | { |
75 | struct video_device *vdev = to_video_device(cd); | 77 | struct video_device *vdev = to_video_device(cd); |
76 | 78 | ||
77 | return sprintf(buf, "%.*s\n", (int)sizeof(vdev->name), vdev->name); | 79 | return sprintf(buf, "%.*s\n", (int)sizeof(vdev->name), vdev->name); |
78 | } | 80 | } |
81 | static DEVICE_ATTR_RO(name); | ||
79 | 82 | ||
80 | static struct device_attribute video_device_attrs[] = { | 83 | static struct attribute *video_device_attrs[] = { |
81 | __ATTR(name, S_IRUGO, show_name, NULL), | 84 | &dev_attr_name.attr, |
82 | __ATTR(debug, 0644, show_debug, set_debug), | 85 | &dev_attr_debug.attr, |
83 | __ATTR(index, S_IRUGO, show_index, NULL), | 86 | &dev_attr_index.attr, |
84 | __ATTR_NULL | 87 | NULL, |
85 | }; | 88 | }; |
89 | ATTRIBUTE_GROUPS(video_device); | ||
86 | 90 | ||
87 | /* | 91 | /* |
88 | * Active devices | 92 | * Active devices |
@@ -217,7 +221,7 @@ static void v4l2_device_release(struct device *cd) | |||
217 | 221 | ||
218 | static struct class video_class = { | 222 | static struct class video_class = { |
219 | .name = VIDEO_NAME, | 223 | .name = VIDEO_NAME, |
220 | .dev_attrs = video_device_attrs, | 224 | .dev_groups = video_device_groups, |
221 | }; | 225 | }; |
222 | 226 | ||
223 | struct video_device *video_devdata(struct file *file) | 227 | struct video_device *video_devdata(struct file *file) |
diff --git a/drivers/misc/c2port/core.c b/drivers/misc/c2port/core.c index f32550a74bdd..464419b36440 100644 --- a/drivers/misc/c2port/core.c +++ b/drivers/misc/c2port/core.c | |||
@@ -311,6 +311,7 @@ static ssize_t c2port_show_name(struct device *dev, | |||
311 | 311 | ||
312 | return sprintf(buf, "%s\n", c2dev->name); | 312 | return sprintf(buf, "%s\n", c2dev->name); |
313 | } | 313 | } |
314 | static DEVICE_ATTR(name, 0444, c2port_show_name, NULL); | ||
314 | 315 | ||
315 | static ssize_t c2port_show_flash_blocks_num(struct device *dev, | 316 | static ssize_t c2port_show_flash_blocks_num(struct device *dev, |
316 | struct device_attribute *attr, char *buf) | 317 | struct device_attribute *attr, char *buf) |
@@ -320,6 +321,7 @@ static ssize_t c2port_show_flash_blocks_num(struct device *dev, | |||
320 | 321 | ||
321 | return sprintf(buf, "%d\n", ops->blocks_num); | 322 | return sprintf(buf, "%d\n", ops->blocks_num); |
322 | } | 323 | } |
324 | static DEVICE_ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL); | ||
323 | 325 | ||
324 | static ssize_t c2port_show_flash_block_size(struct device *dev, | 326 | static ssize_t c2port_show_flash_block_size(struct device *dev, |
325 | struct device_attribute *attr, char *buf) | 327 | struct device_attribute *attr, char *buf) |
@@ -329,6 +331,7 @@ static ssize_t c2port_show_flash_block_size(struct device *dev, | |||
329 | 331 | ||
330 | return sprintf(buf, "%d\n", ops->block_size); | 332 | return sprintf(buf, "%d\n", ops->block_size); |
331 | } | 333 | } |
334 | static DEVICE_ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL); | ||
332 | 335 | ||
333 | static ssize_t c2port_show_flash_size(struct device *dev, | 336 | static ssize_t c2port_show_flash_size(struct device *dev, |
334 | struct device_attribute *attr, char *buf) | 337 | struct device_attribute *attr, char *buf) |
@@ -338,18 +341,18 @@ static ssize_t c2port_show_flash_size(struct device *dev, | |||
338 | 341 | ||
339 | return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size); | 342 | return sprintf(buf, "%d\n", ops->blocks_num * ops->block_size); |
340 | } | 343 | } |
344 | static DEVICE_ATTR(flash_size, 0444, c2port_show_flash_size, NULL); | ||
341 | 345 | ||
342 | static ssize_t c2port_show_access(struct device *dev, | 346 | static ssize_t access_show(struct device *dev, struct device_attribute *attr, |
343 | struct device_attribute *attr, char *buf) | 347 | char *buf) |
344 | { | 348 | { |
345 | struct c2port_device *c2dev = dev_get_drvdata(dev); | 349 | struct c2port_device *c2dev = dev_get_drvdata(dev); |
346 | 350 | ||
347 | return sprintf(buf, "%d\n", c2dev->access); | 351 | return sprintf(buf, "%d\n", c2dev->access); |
348 | } | 352 | } |
349 | 353 | ||
350 | static ssize_t c2port_store_access(struct device *dev, | 354 | static ssize_t access_store(struct device *dev, struct device_attribute *attr, |
351 | struct device_attribute *attr, | 355 | const char *buf, size_t count) |
352 | const char *buf, size_t count) | ||
353 | { | 356 | { |
354 | struct c2port_device *c2dev = dev_get_drvdata(dev); | 357 | struct c2port_device *c2dev = dev_get_drvdata(dev); |
355 | struct c2port_ops *ops = c2dev->ops; | 358 | struct c2port_ops *ops = c2dev->ops; |
@@ -375,6 +378,7 @@ static ssize_t c2port_store_access(struct device *dev, | |||
375 | 378 | ||
376 | return count; | 379 | return count; |
377 | } | 380 | } |
381 | static DEVICE_ATTR_RW(access); | ||
378 | 382 | ||
379 | static ssize_t c2port_store_reset(struct device *dev, | 383 | static ssize_t c2port_store_reset(struct device *dev, |
380 | struct device_attribute *attr, | 384 | struct device_attribute *attr, |
@@ -395,6 +399,7 @@ static ssize_t c2port_store_reset(struct device *dev, | |||
395 | 399 | ||
396 | return count; | 400 | return count; |
397 | } | 401 | } |
402 | static DEVICE_ATTR(reset, 0200, NULL, c2port_store_reset); | ||
398 | 403 | ||
399 | static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf) | 404 | static ssize_t __c2port_show_dev_id(struct c2port_device *dev, char *buf) |
400 | { | 405 | { |
@@ -431,6 +436,7 @@ static ssize_t c2port_show_dev_id(struct device *dev, | |||
431 | 436 | ||
432 | return ret; | 437 | return ret; |
433 | } | 438 | } |
439 | static DEVICE_ATTR(dev_id, 0444, c2port_show_dev_id, NULL); | ||
434 | 440 | ||
435 | static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf) | 441 | static ssize_t __c2port_show_rev_id(struct c2port_device *dev, char *buf) |
436 | { | 442 | { |
@@ -467,6 +473,7 @@ static ssize_t c2port_show_rev_id(struct device *dev, | |||
467 | 473 | ||
468 | return ret; | 474 | return ret; |
469 | } | 475 | } |
476 | static DEVICE_ATTR(rev_id, 0444, c2port_show_rev_id, NULL); | ||
470 | 477 | ||
471 | static ssize_t c2port_show_flash_access(struct device *dev, | 478 | static ssize_t c2port_show_flash_access(struct device *dev, |
472 | struct device_attribute *attr, char *buf) | 479 | struct device_attribute *attr, char *buf) |
@@ -536,6 +543,8 @@ static ssize_t c2port_store_flash_access(struct device *dev, | |||
536 | 543 | ||
537 | return count; | 544 | return count; |
538 | } | 545 | } |
546 | static DEVICE_ATTR(flash_access, 0644, c2port_show_flash_access, | ||
547 | c2port_store_flash_access); | ||
539 | 548 | ||
540 | static ssize_t __c2port_write_flash_erase(struct c2port_device *dev) | 549 | static ssize_t __c2port_write_flash_erase(struct c2port_device *dev) |
541 | { | 550 | { |
@@ -616,6 +625,7 @@ static ssize_t c2port_store_flash_erase(struct device *dev, | |||
616 | 625 | ||
617 | return count; | 626 | return count; |
618 | } | 627 | } |
628 | static DEVICE_ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase); | ||
619 | 629 | ||
620 | static ssize_t __c2port_read_flash_data(struct c2port_device *dev, | 630 | static ssize_t __c2port_read_flash_data(struct c2port_device *dev, |
621 | char *buffer, loff_t offset, size_t count) | 631 | 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, | |||
846 | 856 | ||
847 | return ret; | 857 | return ret; |
848 | } | 858 | } |
859 | /* size is computed at run-time */ | ||
860 | static BIN_ATTR(flash_data, 0644, c2port_read_flash_data, | ||
861 | c2port_write_flash_data, 0); | ||
849 | 862 | ||
850 | /* | 863 | /* |
851 | * Class attributes | 864 | * Class attributes |
852 | */ | 865 | */ |
866 | static struct attribute *c2port_attrs[] = { | ||
867 | &dev_attr_name.attr, | ||
868 | &dev_attr_flash_blocks_num.attr, | ||
869 | &dev_attr_flash_block_size.attr, | ||
870 | &dev_attr_flash_size.attr, | ||
871 | &dev_attr_access.attr, | ||
872 | &dev_attr_reset.attr, | ||
873 | &dev_attr_dev_id.attr, | ||
874 | &dev_attr_rev_id.attr, | ||
875 | &dev_attr_flash_access.attr, | ||
876 | &dev_attr_flash_erase.attr, | ||
877 | NULL, | ||
878 | }; | ||
853 | 879 | ||
854 | static struct device_attribute c2port_attrs[] = { | 880 | static struct bin_attribute *c2port_bin_attrs[] = { |
855 | __ATTR(name, 0444, c2port_show_name, NULL), | 881 | &bin_attr_flash_data, |
856 | __ATTR(flash_blocks_num, 0444, c2port_show_flash_blocks_num, NULL), | 882 | NULL, |
857 | __ATTR(flash_block_size, 0444, c2port_show_flash_block_size, NULL), | ||
858 | __ATTR(flash_size, 0444, c2port_show_flash_size, NULL), | ||
859 | __ATTR(access, 0644, c2port_show_access, c2port_store_access), | ||
860 | __ATTR(reset, 0200, NULL, c2port_store_reset), | ||
861 | __ATTR(dev_id, 0444, c2port_show_dev_id, NULL), | ||
862 | __ATTR(rev_id, 0444, c2port_show_rev_id, NULL), | ||
863 | |||
864 | __ATTR(flash_access, 0644, c2port_show_flash_access, | ||
865 | c2port_store_flash_access), | ||
866 | __ATTR(flash_erase, 0200, NULL, c2port_store_flash_erase), | ||
867 | __ATTR_NULL, | ||
868 | }; | 883 | }; |
869 | 884 | ||
870 | static struct bin_attribute c2port_bin_attrs = { | 885 | static const struct attribute_group c2port_group = { |
871 | .attr = { | 886 | .attrs = c2port_attrs, |
872 | .name = "flash_data", | 887 | .bin_attrs = c2port_bin_attrs, |
873 | .mode = 0644 | 888 | }; |
874 | }, | 889 | |
875 | .read = c2port_read_flash_data, | 890 | static const struct attribute_group *c2port_groups[] = { |
876 | .write = c2port_write_flash_data, | 891 | &c2port_group, |
877 | /* .size is computed at run-time */ | 892 | NULL, |
878 | }; | 893 | }; |
879 | 894 | ||
880 | /* | 895 | /* |
@@ -907,6 +922,8 @@ struct c2port_device *c2port_device_register(char *name, | |||
907 | goto error_idr_alloc; | 922 | goto error_idr_alloc; |
908 | c2dev->id = ret; | 923 | c2dev->id = ret; |
909 | 924 | ||
925 | bin_attr_flash_data.size = ops->blocks_num * ops->block_size; | ||
926 | |||
910 | c2dev->dev = device_create(c2port_class, NULL, 0, c2dev, | 927 | c2dev->dev = device_create(c2port_class, NULL, 0, c2dev, |
911 | "c2port%d", c2dev->id); | 928 | "c2port%d", c2dev->id); |
912 | if (unlikely(IS_ERR(c2dev->dev))) { | 929 | if (unlikely(IS_ERR(c2dev->dev))) { |
@@ -919,12 +936,6 @@ struct c2port_device *c2port_device_register(char *name, | |||
919 | c2dev->ops = ops; | 936 | c2dev->ops = ops; |
920 | mutex_init(&c2dev->mutex); | 937 | mutex_init(&c2dev->mutex); |
921 | 938 | ||
922 | /* Create binary file */ | ||
923 | c2port_bin_attrs.size = ops->blocks_num * ops->block_size; | ||
924 | ret = device_create_bin_file(c2dev->dev, &c2port_bin_attrs); | ||
925 | if (unlikely(ret)) | ||
926 | goto error_device_create_bin_file; | ||
927 | |||
928 | /* By default C2 port access is off */ | 939 | /* By default C2 port access is off */ |
929 | c2dev->access = c2dev->flash_access = 0; | 940 | c2dev->access = c2dev->flash_access = 0; |
930 | ops->access(c2dev, 0); | 941 | ops->access(c2dev, 0); |
@@ -937,9 +948,6 @@ struct c2port_device *c2port_device_register(char *name, | |||
937 | 948 | ||
938 | return c2dev; | 949 | return c2dev; |
939 | 950 | ||
940 | error_device_create_bin_file: | ||
941 | device_destroy(c2port_class, 0); | ||
942 | |||
943 | error_device_create: | 951 | error_device_create: |
944 | spin_lock_irq(&c2port_idr_lock); | 952 | spin_lock_irq(&c2port_idr_lock); |
945 | idr_remove(&c2port_idr, c2dev->id); | 953 | idr_remove(&c2port_idr, c2dev->id); |
@@ -959,7 +967,6 @@ void c2port_device_unregister(struct c2port_device *c2dev) | |||
959 | 967 | ||
960 | dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name); | 968 | dev_info(c2dev->dev, "C2 port %s removed\n", c2dev->name); |
961 | 969 | ||
962 | device_remove_bin_file(c2dev->dev, &c2port_bin_attrs); | ||
963 | spin_lock_irq(&c2port_idr_lock); | 970 | spin_lock_irq(&c2port_idr_lock); |
964 | idr_remove(&c2port_idr, c2dev->id); | 971 | idr_remove(&c2port_idr, c2dev->id); |
965 | spin_unlock_irq(&c2port_idr_lock); | 972 | spin_unlock_irq(&c2port_idr_lock); |
@@ -984,7 +991,7 @@ static int __init c2port_init(void) | |||
984 | printk(KERN_ERR "c2port: failed to allocate class\n"); | 991 | printk(KERN_ERR "c2port: failed to allocate class\n"); |
985 | return PTR_ERR(c2port_class); | 992 | return PTR_ERR(c2port_class); |
986 | } | 993 | } |
987 | c2port_class->dev_attrs = c2port_attrs; | 994 | c2port_class->dev_groups = c2port_groups; |
988 | 995 | ||
989 | return 0; | 996 | return 0; |
990 | } | 997 | } |
diff --git a/drivers/misc/enclosure.c b/drivers/misc/enclosure.c index 00e5fcac8fdf..0e8df41aaf14 100644 --- a/drivers/misc/enclosure.c +++ b/drivers/misc/enclosure.c | |||
@@ -239,7 +239,7 @@ static void enclosure_component_release(struct device *dev) | |||
239 | put_device(dev->parent); | 239 | put_device(dev->parent); |
240 | } | 240 | } |
241 | 241 | ||
242 | static const struct attribute_group *enclosure_groups[]; | 242 | static const struct attribute_group *enclosure_component_groups[]; |
243 | 243 | ||
244 | /** | 244 | /** |
245 | * enclosure_component_register - add a particular component to an enclosure | 245 | * enclosure_component_register - add a particular component to an enclosure |
@@ -282,7 +282,7 @@ enclosure_component_register(struct enclosure_device *edev, | |||
282 | dev_set_name(cdev, "%u", number); | 282 | dev_set_name(cdev, "%u", number); |
283 | 283 | ||
284 | cdev->release = enclosure_component_release; | 284 | cdev->release = enclosure_component_release; |
285 | cdev->groups = enclosure_groups; | 285 | cdev->groups = enclosure_component_groups; |
286 | 286 | ||
287 | err = device_register(cdev); | 287 | err = device_register(cdev); |
288 | if (err) { | 288 | if (err) { |
@@ -365,25 +365,26 @@ EXPORT_SYMBOL_GPL(enclosure_remove_device); | |||
365 | * sysfs pieces below | 365 | * sysfs pieces below |
366 | */ | 366 | */ |
367 | 367 | ||
368 | static ssize_t enclosure_show_components(struct device *cdev, | 368 | static ssize_t components_show(struct device *cdev, |
369 | struct device_attribute *attr, | 369 | struct device_attribute *attr, char *buf) |
370 | char *buf) | ||
371 | { | 370 | { |
372 | struct enclosure_device *edev = to_enclosure_device(cdev); | 371 | struct enclosure_device *edev = to_enclosure_device(cdev); |
373 | 372 | ||
374 | return snprintf(buf, 40, "%d\n", edev->components); | 373 | return snprintf(buf, 40, "%d\n", edev->components); |
375 | } | 374 | } |
375 | static DEVICE_ATTR_RO(components); | ||
376 | 376 | ||
377 | static struct device_attribute enclosure_attrs[] = { | 377 | static struct attribute *enclosure_class_attrs[] = { |
378 | __ATTR(components, S_IRUGO, enclosure_show_components, NULL), | 378 | &dev_attr_components.attr, |
379 | __ATTR_NULL | 379 | NULL, |
380 | }; | 380 | }; |
381 | ATTRIBUTE_GROUPS(enclosure_class); | ||
381 | 382 | ||
382 | static struct class enclosure_class = { | 383 | static struct class enclosure_class = { |
383 | .name = "enclosure", | 384 | .name = "enclosure", |
384 | .owner = THIS_MODULE, | 385 | .owner = THIS_MODULE, |
385 | .dev_release = enclosure_release, | 386 | .dev_release = enclosure_release, |
386 | .dev_attrs = enclosure_attrs, | 387 | .dev_groups = enclosure_class_groups, |
387 | }; | 388 | }; |
388 | 389 | ||
389 | static const char *const enclosure_status [] = { | 390 | static const char *const enclosure_status [] = { |
@@ -536,15 +537,7 @@ static struct attribute *enclosure_component_attrs[] = { | |||
536 | &dev_attr_type.attr, | 537 | &dev_attr_type.attr, |
537 | NULL | 538 | NULL |
538 | }; | 539 | }; |
539 | 540 | ATTRIBUTE_GROUPS(enclosure_component); | |
540 | static struct attribute_group enclosure_group = { | ||
541 | .attrs = enclosure_component_attrs, | ||
542 | }; | ||
543 | |||
544 | static const struct attribute_group *enclosure_groups[] = { | ||
545 | &enclosure_group, | ||
546 | NULL | ||
547 | }; | ||
548 | 541 | ||
549 | static int __init enclosure_init(void) | 542 | static int __init enclosure_init(void) |
550 | { | 543 | { |
diff --git a/drivers/misc/mei/bus.c b/drivers/misc/mei/bus.c index a150a42ed4af..6d0282c08a06 100644 --- a/drivers/misc/mei/bus.c +++ b/drivers/misc/mei/bus.c | |||
@@ -108,11 +108,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *a, | |||
108 | 108 | ||
109 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; | 109 | return (len >= PAGE_SIZE) ? (PAGE_SIZE - 1) : len; |
110 | } | 110 | } |
111 | static DEVICE_ATTR_RO(modalias); | ||
111 | 112 | ||
112 | static struct device_attribute mei_cl_dev_attrs[] = { | 113 | static struct attribute *mei_cl_dev_attrs[] = { |
113 | __ATTR_RO(modalias), | 114 | &dev_attr_modalias.attr, |
114 | __ATTR_NULL, | 115 | NULL, |
115 | }; | 116 | }; |
117 | ATTRIBUTE_GROUPS(mei_cl_dev); | ||
116 | 118 | ||
117 | static int mei_cl_uevent(struct device *dev, struct kobj_uevent_env *env) | 119 | static int mei_cl_uevent(struct device *dev, struct kobj_uevent_env *env) |
118 | { | 120 | { |
@@ -124,7 +126,7 @@ static int mei_cl_uevent(struct device *dev, struct kobj_uevent_env *env) | |||
124 | 126 | ||
125 | static struct bus_type mei_cl_bus_type = { | 127 | static struct bus_type mei_cl_bus_type = { |
126 | .name = "mei", | 128 | .name = "mei", |
127 | .dev_attrs = mei_cl_dev_attrs, | 129 | .dev_groups = mei_cl_dev_groups, |
128 | .match = mei_cl_device_match, | 130 | .match = mei_cl_device_match, |
129 | .probe = mei_cl_device_probe, | 131 | .probe = mei_cl_device_probe, |
130 | .remove = mei_cl_device_remove, | 132 | .remove = mei_cl_device_remove, |
diff --git a/drivers/net/ethernet/sun/niu.c b/drivers/net/ethernet/sun/niu.c index fa322409bff3..52b2adf63cbf 100644 --- a/drivers/net/ethernet/sun/niu.c +++ b/drivers/net/ethernet/sun/niu.c | |||
@@ -9478,7 +9478,7 @@ static struct niu_parent *niu_new_parent(struct niu *np, | |||
9478 | if (IS_ERR(plat_dev)) | 9478 | if (IS_ERR(plat_dev)) |
9479 | return NULL; | 9479 | return NULL; |
9480 | 9480 | ||
9481 | for (i = 0; attr_name(niu_parent_attributes[i]); i++) { | 9481 | for (i = 0; niu_parent_attributes[i].attr.name; i++) { |
9482 | int err = device_create_file(&plat_dev->dev, | 9482 | int err = device_create_file(&plat_dev->dev, |
9483 | &niu_parent_attributes[i]); | 9483 | &niu_parent_attributes[i]); |
9484 | if (err) | 9484 | if (err) |
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index b13344c59808..6e02c953d888 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -693,11 +693,13 @@ static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | |||
693 | 693 | ||
694 | return sprintf(buf, "wmi:%s\n", guid_string); | 694 | return sprintf(buf, "wmi:%s\n", guid_string); |
695 | } | 695 | } |
696 | static DEVICE_ATTR_RO(modalias); | ||
696 | 697 | ||
697 | static struct device_attribute wmi_dev_attrs[] = { | 698 | static struct attribute *wmi_attrs[] = { |
698 | __ATTR_RO(modalias), | 699 | &dev_attr_modalias.attr, |
699 | __ATTR_NULL | 700 | NULL, |
700 | }; | 701 | }; |
702 | ATTRIBUTE_GROUPS(wmi); | ||
701 | 703 | ||
702 | static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) | 704 | static int wmi_dev_uevent(struct device *dev, struct kobj_uevent_env *env) |
703 | { | 705 | { |
@@ -732,7 +734,7 @@ static struct class wmi_class = { | |||
732 | .name = "wmi", | 734 | .name = "wmi", |
733 | .dev_release = wmi_dev_free, | 735 | .dev_release = wmi_dev_free, |
734 | .dev_uevent = wmi_dev_uevent, | 736 | .dev_uevent = wmi_dev_uevent, |
735 | .dev_attrs = wmi_dev_attrs, | 737 | .dev_groups = wmi_groups, |
736 | }; | 738 | }; |
737 | 739 | ||
738 | static int wmi_create_device(const struct guid_block *gblock, | 740 | static int wmi_create_device(const struct guid_block *gblock, |
diff --git a/drivers/pps/pps.c b/drivers/pps/pps.c index 7173e3ad475d..2f07cd615665 100644 --- a/drivers/pps/pps.c +++ b/drivers/pps/pps.c | |||
@@ -406,7 +406,7 @@ static int __init pps_init(void) | |||
406 | pr_err("failed to allocate class\n"); | 406 | pr_err("failed to allocate class\n"); |
407 | return PTR_ERR(pps_class); | 407 | return PTR_ERR(pps_class); |
408 | } | 408 | } |
409 | pps_class->dev_attrs = pps_attrs; | 409 | pps_class->dev_groups = pps_groups; |
410 | 410 | ||
411 | err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); | 411 | err = alloc_chrdev_region(&pps_devt, 0, PPS_MAX_SOURCES, "pps"); |
412 | if (err < 0) { | 412 | if (err < 0) { |
diff --git a/drivers/pps/sysfs.c b/drivers/pps/sysfs.c index ef0978c71eee..aefb75d67094 100644 --- a/drivers/pps/sysfs.c +++ b/drivers/pps/sysfs.c | |||
@@ -29,8 +29,8 @@ | |||
29 | * Attribute functions | 29 | * Attribute functions |
30 | */ | 30 | */ |
31 | 31 | ||
32 | static ssize_t pps_show_assert(struct device *dev, | 32 | static ssize_t assert_show(struct device *dev, struct device_attribute *attr, |
33 | struct device_attribute *attr, char *buf) | 33 | char *buf) |
34 | { | 34 | { |
35 | struct pps_device *pps = dev_get_drvdata(dev); | 35 | struct pps_device *pps = dev_get_drvdata(dev); |
36 | 36 | ||
@@ -41,9 +41,10 @@ static ssize_t pps_show_assert(struct device *dev, | |||
41 | (long long) pps->assert_tu.sec, pps->assert_tu.nsec, | 41 | (long long) pps->assert_tu.sec, pps->assert_tu.nsec, |
42 | pps->assert_sequence); | 42 | pps->assert_sequence); |
43 | } | 43 | } |
44 | static DEVICE_ATTR_RO(assert); | ||
44 | 45 | ||
45 | static ssize_t pps_show_clear(struct device *dev, | 46 | static ssize_t clear_show(struct device *dev, struct device_attribute *attr, |
46 | struct device_attribute *attr, char *buf) | 47 | char *buf) |
47 | { | 48 | { |
48 | struct pps_device *pps = dev_get_drvdata(dev); | 49 | struct pps_device *pps = dev_get_drvdata(dev); |
49 | 50 | ||
@@ -54,45 +55,59 @@ static ssize_t pps_show_clear(struct device *dev, | |||
54 | (long long) pps->clear_tu.sec, pps->clear_tu.nsec, | 55 | (long long) pps->clear_tu.sec, pps->clear_tu.nsec, |
55 | pps->clear_sequence); | 56 | pps->clear_sequence); |
56 | } | 57 | } |
58 | static DEVICE_ATTR_RO(clear); | ||
57 | 59 | ||
58 | static ssize_t pps_show_mode(struct device *dev, | 60 | static ssize_t mode_show(struct device *dev, struct device_attribute *attr, |
59 | struct device_attribute *attr, char *buf) | 61 | char *buf) |
60 | { | 62 | { |
61 | struct pps_device *pps = dev_get_drvdata(dev); | 63 | struct pps_device *pps = dev_get_drvdata(dev); |
62 | 64 | ||
63 | return sprintf(buf, "%4x\n", pps->info.mode); | 65 | return sprintf(buf, "%4x\n", pps->info.mode); |
64 | } | 66 | } |
67 | static DEVICE_ATTR_RO(mode); | ||
65 | 68 | ||
66 | static ssize_t pps_show_echo(struct device *dev, | 69 | static ssize_t echo_show(struct device *dev, struct device_attribute *attr, |
67 | struct device_attribute *attr, char *buf) | 70 | char *buf) |
68 | { | 71 | { |
69 | struct pps_device *pps = dev_get_drvdata(dev); | 72 | struct pps_device *pps = dev_get_drvdata(dev); |
70 | 73 | ||
71 | return sprintf(buf, "%d\n", !!pps->info.echo); | 74 | return sprintf(buf, "%d\n", !!pps->info.echo); |
72 | } | 75 | } |
76 | static DEVICE_ATTR_RO(echo); | ||
73 | 77 | ||
74 | static ssize_t pps_show_name(struct device *dev, | 78 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, |
75 | struct device_attribute *attr, char *buf) | 79 | char *buf) |
76 | { | 80 | { |
77 | struct pps_device *pps = dev_get_drvdata(dev); | 81 | struct pps_device *pps = dev_get_drvdata(dev); |
78 | 82 | ||
79 | return sprintf(buf, "%s\n", pps->info.name); | 83 | return sprintf(buf, "%s\n", pps->info.name); |
80 | } | 84 | } |
85 | static DEVICE_ATTR_RO(name); | ||
81 | 86 | ||
82 | static ssize_t pps_show_path(struct device *dev, | 87 | static ssize_t path_show(struct device *dev, struct device_attribute *attr, |
83 | struct device_attribute *attr, char *buf) | 88 | char *buf) |
84 | { | 89 | { |
85 | struct pps_device *pps = dev_get_drvdata(dev); | 90 | struct pps_device *pps = dev_get_drvdata(dev); |
86 | 91 | ||
87 | return sprintf(buf, "%s\n", pps->info.path); | 92 | return sprintf(buf, "%s\n", pps->info.path); |
88 | } | 93 | } |
94 | static DEVICE_ATTR_RO(path); | ||
95 | |||
96 | static struct attribute *pps_attrs[] = { | ||
97 | &dev_attr_assert.attr, | ||
98 | &dev_attr_clear.attr, | ||
99 | &dev_attr_mode.attr, | ||
100 | &dev_attr_echo.attr, | ||
101 | &dev_attr_name.attr, | ||
102 | &dev_attr_path.attr, | ||
103 | NULL, | ||
104 | }; | ||
105 | |||
106 | static const struct attribute_group pps_group = { | ||
107 | .attrs = pps_attrs, | ||
108 | }; | ||
89 | 109 | ||
90 | struct device_attribute pps_attrs[] = { | 110 | const struct attribute_group *pps_groups[] = { |
91 | __ATTR(assert, S_IRUGO, pps_show_assert, NULL), | 111 | &pps_group, |
92 | __ATTR(clear, S_IRUGO, pps_show_clear, NULL), | 112 | NULL, |
93 | __ATTR(mode, S_IRUGO, pps_show_mode, NULL), | ||
94 | __ATTR(echo, S_IRUGO, pps_show_echo, NULL), | ||
95 | __ATTR(name, S_IRUGO, pps_show_name, NULL), | ||
96 | __ATTR(path, S_IRUGO, pps_show_path, NULL), | ||
97 | __ATTR_NULL, | ||
98 | }; | 113 | }; |
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c index 4a8c388364ca..a8319b266643 100644 --- a/drivers/ptp/ptp_clock.c +++ b/drivers/ptp/ptp_clock.c | |||
@@ -330,7 +330,7 @@ static int __init ptp_init(void) | |||
330 | goto no_region; | 330 | goto no_region; |
331 | } | 331 | } |
332 | 332 | ||
333 | ptp_class->dev_attrs = ptp_dev_attrs; | 333 | ptp_class->dev_groups = ptp_groups; |
334 | pr_info("PTP clock support registered\n"); | 334 | pr_info("PTP clock support registered\n"); |
335 | return 0; | 335 | return 0; |
336 | 336 | ||
diff --git a/drivers/ptp/ptp_private.h b/drivers/ptp/ptp_private.h index 69d32070cc65..df03f2e30ad9 100644 --- a/drivers/ptp/ptp_private.h +++ b/drivers/ptp/ptp_private.h | |||
@@ -84,7 +84,7 @@ uint ptp_poll(struct posix_clock *pc, | |||
84 | * see ptp_sysfs.c | 84 | * see ptp_sysfs.c |
85 | */ | 85 | */ |
86 | 86 | ||
87 | extern struct device_attribute ptp_dev_attrs[]; | 87 | extern const struct attribute_group *ptp_groups[]; |
88 | 88 | ||
89 | int ptp_cleanup_sysfs(struct ptp_clock *ptp); | 89 | int ptp_cleanup_sysfs(struct ptp_clock *ptp); |
90 | 90 | ||
diff --git a/drivers/ptp/ptp_sysfs.c b/drivers/ptp/ptp_sysfs.c index 2f93926ac976..13ec5311746a 100644 --- a/drivers/ptp/ptp_sysfs.c +++ b/drivers/ptp/ptp_sysfs.c | |||
@@ -27,36 +27,43 @@ static ssize_t clock_name_show(struct device *dev, | |||
27 | struct ptp_clock *ptp = dev_get_drvdata(dev); | 27 | struct ptp_clock *ptp = dev_get_drvdata(dev); |
28 | return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name); | 28 | return snprintf(page, PAGE_SIZE-1, "%s\n", ptp->info->name); |
29 | } | 29 | } |
30 | static DEVICE_ATTR(clock_name, 0444, clock_name_show, NULL); | ||
30 | 31 | ||
31 | #define PTP_SHOW_INT(name) \ | 32 | #define PTP_SHOW_INT(name, var) \ |
32 | static ssize_t name##_show(struct device *dev, \ | 33 | static ssize_t var##_show(struct device *dev, \ |
33 | struct device_attribute *attr, char *page) \ | 34 | struct device_attribute *attr, char *page) \ |
34 | { \ | 35 | { \ |
35 | struct ptp_clock *ptp = dev_get_drvdata(dev); \ | 36 | struct ptp_clock *ptp = dev_get_drvdata(dev); \ |
36 | return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->name); \ | 37 | return snprintf(page, PAGE_SIZE-1, "%d\n", ptp->info->var); \ |
37 | } | 38 | } \ |
38 | 39 | static DEVICE_ATTR(name, 0444, var##_show, NULL); | |
39 | PTP_SHOW_INT(max_adj); | 40 | |
40 | PTP_SHOW_INT(n_alarm); | 41 | PTP_SHOW_INT(max_adjustment, max_adj); |
41 | PTP_SHOW_INT(n_ext_ts); | 42 | PTP_SHOW_INT(n_alarms, n_alarm); |
42 | PTP_SHOW_INT(n_per_out); | 43 | PTP_SHOW_INT(n_external_timestamps, n_ext_ts); |
43 | PTP_SHOW_INT(pps); | 44 | PTP_SHOW_INT(n_periodic_outputs, n_per_out); |
45 | PTP_SHOW_INT(pps_available, pps); | ||
46 | |||
47 | static struct attribute *ptp_attrs[] = { | ||
48 | &dev_attr_clock_name.attr, | ||
49 | &dev_attr_max_adjustment.attr, | ||
50 | &dev_attr_n_alarms.attr, | ||
51 | &dev_attr_n_external_timestamps.attr, | ||
52 | &dev_attr_n_periodic_outputs.attr, | ||
53 | &dev_attr_pps_available.attr, | ||
54 | NULL, | ||
55 | }; | ||
44 | 56 | ||
45 | #define PTP_RO_ATTR(_var, _name) { \ | 57 | static const struct attribute_group ptp_group = { |
46 | .attr = { .name = __stringify(_name), .mode = 0444 }, \ | 58 | .attrs = ptp_attrs, |
47 | .show = _var##_show, \ | 59 | }; |
48 | } | ||
49 | 60 | ||
50 | struct device_attribute ptp_dev_attrs[] = { | 61 | const struct attribute_group *ptp_groups[] = { |
51 | PTP_RO_ATTR(clock_name, clock_name), | 62 | &ptp_group, |
52 | PTP_RO_ATTR(max_adj, max_adjustment), | 63 | NULL, |
53 | PTP_RO_ATTR(n_alarm, n_alarms), | ||
54 | PTP_RO_ATTR(n_ext_ts, n_external_timestamps), | ||
55 | PTP_RO_ATTR(n_per_out, n_periodic_outputs), | ||
56 | PTP_RO_ATTR(pps, pps_available), | ||
57 | __ATTR_NULL, | ||
58 | }; | 64 | }; |
59 | 65 | ||
66 | |||
60 | static ssize_t extts_enable_store(struct device *dev, | 67 | static ssize_t extts_enable_store(struct device *dev, |
61 | struct device_attribute *attr, | 68 | struct device_attribute *attr, |
62 | const char *buf, size_t count) | 69 | const char *buf, size_t count) |
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c index 4b26f8672b2d..babd43bf3ddc 100644 --- a/drivers/rtc/rtc-sysfs.c +++ b/drivers/rtc/rtc-sysfs.c | |||
@@ -25,15 +25,14 @@ | |||
25 | */ | 25 | */ |
26 | 26 | ||
27 | static ssize_t | 27 | static ssize_t |
28 | rtc_sysfs_show_name(struct device *dev, struct device_attribute *attr, | 28 | name_show(struct device *dev, struct device_attribute *attr, char *buf) |
29 | char *buf) | ||
30 | { | 29 | { |
31 | return sprintf(buf, "%s\n", to_rtc_device(dev)->name); | 30 | return sprintf(buf, "%s\n", to_rtc_device(dev)->name); |
32 | } | 31 | } |
32 | static DEVICE_ATTR_RO(name); | ||
33 | 33 | ||
34 | static ssize_t | 34 | static ssize_t |
35 | rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr, | 35 | date_show(struct device *dev, struct device_attribute *attr, char *buf) |
36 | char *buf) | ||
37 | { | 36 | { |
38 | ssize_t retval; | 37 | ssize_t retval; |
39 | struct rtc_time tm; | 38 | struct rtc_time tm; |
@@ -46,10 +45,10 @@ rtc_sysfs_show_date(struct device *dev, struct device_attribute *attr, | |||
46 | 45 | ||
47 | return retval; | 46 | return retval; |
48 | } | 47 | } |
48 | static DEVICE_ATTR_RO(date); | ||
49 | 49 | ||
50 | static ssize_t | 50 | static ssize_t |
51 | rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr, | 51 | time_show(struct device *dev, struct device_attribute *attr, char *buf) |
52 | char *buf) | ||
53 | { | 52 | { |
54 | ssize_t retval; | 53 | ssize_t retval; |
55 | struct rtc_time tm; | 54 | struct rtc_time tm; |
@@ -62,10 +61,10 @@ rtc_sysfs_show_time(struct device *dev, struct device_attribute *attr, | |||
62 | 61 | ||
63 | return retval; | 62 | return retval; |
64 | } | 63 | } |
64 | static DEVICE_ATTR_RO(time); | ||
65 | 65 | ||
66 | static ssize_t | 66 | static ssize_t |
67 | rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr, | 67 | since_epoch_show(struct device *dev, struct device_attribute *attr, char *buf) |
68 | char *buf) | ||
69 | { | 68 | { |
70 | ssize_t retval; | 69 | ssize_t retval; |
71 | struct rtc_time tm; | 70 | struct rtc_time tm; |
@@ -79,16 +78,16 @@ rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr, | |||
79 | 78 | ||
80 | return retval; | 79 | return retval; |
81 | } | 80 | } |
81 | static DEVICE_ATTR_RO(since_epoch); | ||
82 | 82 | ||
83 | static ssize_t | 83 | static ssize_t |
84 | rtc_sysfs_show_max_user_freq(struct device *dev, struct device_attribute *attr, | 84 | max_user_freq_show(struct device *dev, struct device_attribute *attr, char *buf) |
85 | char *buf) | ||
86 | { | 85 | { |
87 | return sprintf(buf, "%d\n", to_rtc_device(dev)->max_user_freq); | 86 | return sprintf(buf, "%d\n", to_rtc_device(dev)->max_user_freq); |
88 | } | 87 | } |
89 | 88 | ||
90 | static ssize_t | 89 | static ssize_t |
91 | rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr, | 90 | max_user_freq_store(struct device *dev, struct device_attribute *attr, |
92 | const char *buf, size_t n) | 91 | const char *buf, size_t n) |
93 | { | 92 | { |
94 | struct rtc_device *rtc = to_rtc_device(dev); | 93 | 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, | |||
101 | 100 | ||
102 | return n; | 101 | return n; |
103 | } | 102 | } |
103 | static DEVICE_ATTR_RW(max_user_freq); | ||
104 | 104 | ||
105 | /** | 105 | /** |
106 | * rtc_sysfs_show_hctosys - indicate if the given RTC set the system time | 106 | * 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, | |||
109 | * boot or resume event. | 109 | * boot or resume event. |
110 | */ | 110 | */ |
111 | static ssize_t | 111 | static ssize_t |
112 | rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, | 112 | hctosys_show(struct device *dev, struct device_attribute *attr, char *buf) |
113 | char *buf) | ||
114 | { | 113 | { |
115 | #ifdef CONFIG_RTC_HCTOSYS_DEVICE | 114 | #ifdef CONFIG_RTC_HCTOSYS_DEVICE |
116 | if (rtc_hctosys_ret == 0 && | 115 | if (rtc_hctosys_ret == 0 && |
@@ -121,17 +120,18 @@ rtc_sysfs_show_hctosys(struct device *dev, struct device_attribute *attr, | |||
121 | #endif | 120 | #endif |
122 | return sprintf(buf, "0\n"); | 121 | return sprintf(buf, "0\n"); |
123 | } | 122 | } |
124 | 123 | static DEVICE_ATTR_RO(hctosys); | |
125 | static struct device_attribute rtc_attrs[] = { | 124 | |
126 | __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL), | 125 | static struct attribute *rtc_attrs[] = { |
127 | __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL), | 126 | &dev_attr_name.attr, |
128 | __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL), | 127 | &dev_attr_date.attr, |
129 | __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL), | 128 | &dev_attr_time.attr, |
130 | __ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq, | 129 | &dev_attr_since_epoch.attr, |
131 | rtc_sysfs_set_max_user_freq), | 130 | &dev_attr_max_user_freq.attr, |
132 | __ATTR(hctosys, S_IRUGO, rtc_sysfs_show_hctosys, NULL), | 131 | &dev_attr_hctosys.attr, |
133 | { }, | 132 | NULL, |
134 | }; | 133 | }; |
134 | ATTRIBUTE_GROUPS(rtc); | ||
135 | 135 | ||
136 | static ssize_t | 136 | static ssize_t |
137 | rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, | 137 | rtc_sysfs_show_wakealarm(struct device *dev, struct device_attribute *attr, |
@@ -261,5 +261,5 @@ void rtc_sysfs_del_device(struct rtc_device *rtc) | |||
261 | 261 | ||
262 | void __init rtc_sysfs_init(struct class *rtc_class) | 262 | void __init rtc_sysfs_init(struct class *rtc_class) |
263 | { | 263 | { |
264 | rtc_class->dev_attrs = rtc_attrs; | 264 | rtc_class->dev_groups = rtc_groups; |
265 | } | 265 | } |
diff --git a/drivers/scsi/osd/osd_uld.c b/drivers/scsi/osd/osd_uld.c index 9d86947d67fe..e1d9a4c4c4b3 100644 --- a/drivers/scsi/osd/osd_uld.c +++ b/drivers/scsi/osd/osd_uld.c | |||
@@ -107,6 +107,7 @@ static ssize_t osdname_show(struct device *dev, struct device_attribute *attr, | |||
107 | class_dev); | 107 | class_dev); |
108 | return sprintf(buf, "%s\n", ould->odi.osdname); | 108 | return sprintf(buf, "%s\n", ould->odi.osdname); |
109 | } | 109 | } |
110 | static DEVICE_ATTR_RO(osdname); | ||
110 | 111 | ||
111 | static ssize_t systemid_show(struct device *dev, struct device_attribute *attr, | 112 | static ssize_t systemid_show(struct device *dev, struct device_attribute *attr, |
112 | char *buf) | 113 | char *buf) |
@@ -117,17 +118,19 @@ static ssize_t systemid_show(struct device *dev, struct device_attribute *attr, | |||
117 | memcpy(buf, ould->odi.systemid, ould->odi.systemid_len); | 118 | memcpy(buf, ould->odi.systemid, ould->odi.systemid_len); |
118 | return ould->odi.systemid_len; | 119 | return ould->odi.systemid_len; |
119 | } | 120 | } |
121 | static DEVICE_ATTR_RO(systemid); | ||
120 | 122 | ||
121 | static struct device_attribute osd_uld_attrs[] = { | 123 | static struct attribute *osd_uld_attrs[] = { |
122 | __ATTR(osdname, S_IRUGO, osdname_show, NULL), | 124 | &dev_attr_osdname.attr, |
123 | __ATTR(systemid, S_IRUGO, systemid_show, NULL), | 125 | &dev_attr_systemid.attr, |
124 | __ATTR_NULL, | 126 | NULL, |
125 | }; | 127 | }; |
128 | ATTRIBUTE_GROUPS(osd_uld); | ||
126 | 129 | ||
127 | static struct class osd_uld_class = { | 130 | static struct class osd_uld_class = { |
128 | .owner = THIS_MODULE, | 131 | .owner = THIS_MODULE, |
129 | .name = "scsi_osd", | 132 | .name = "scsi_osd", |
130 | .dev_attrs = osd_uld_attrs, | 133 | .dev_groups = osd_uld_groups, |
131 | }; | 134 | }; |
132 | 135 | ||
133 | /* | 136 | /* |
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c index f4a197b2d1fd..6d50e3033228 100644 --- a/drivers/staging/comedi/comedi_fops.c +++ b/drivers/staging/comedi/comedi_fops.c | |||
@@ -262,7 +262,7 @@ static int resize_async_buffer(struct comedi_device *dev, | |||
262 | 262 | ||
263 | /* sysfs attribute files */ | 263 | /* sysfs attribute files */ |
264 | 264 | ||
265 | static ssize_t show_max_read_buffer_kb(struct device *csdev, | 265 | static ssize_t max_read_buffer_kb_show(struct device *csdev, |
266 | struct device_attribute *attr, char *buf) | 266 | struct device_attribute *attr, char *buf) |
267 | { | 267 | { |
268 | unsigned int minor = MINOR(csdev->devt); | 268 | unsigned int minor = MINOR(csdev->devt); |
@@ -283,7 +283,7 @@ static ssize_t show_max_read_buffer_kb(struct device *csdev, | |||
283 | return snprintf(buf, PAGE_SIZE, "%i\n", size); | 283 | return snprintf(buf, PAGE_SIZE, "%i\n", size); |
284 | } | 284 | } |
285 | 285 | ||
286 | static ssize_t store_max_read_buffer_kb(struct device *csdev, | 286 | static ssize_t max_read_buffer_kb_store(struct device *csdev, |
287 | struct device_attribute *attr, | 287 | struct device_attribute *attr, |
288 | const char *buf, size_t count) | 288 | const char *buf, size_t count) |
289 | { | 289 | { |
@@ -314,8 +314,9 @@ static ssize_t store_max_read_buffer_kb(struct device *csdev, | |||
314 | 314 | ||
315 | return err ? err : count; | 315 | return err ? err : count; |
316 | } | 316 | } |
317 | static DEVICE_ATTR_RW(max_read_buffer_kb); | ||
317 | 318 | ||
318 | static ssize_t show_read_buffer_kb(struct device *csdev, | 319 | static ssize_t read_buffer_kb_show(struct device *csdev, |
319 | struct device_attribute *attr, char *buf) | 320 | struct device_attribute *attr, char *buf) |
320 | { | 321 | { |
321 | unsigned int minor = MINOR(csdev->devt); | 322 | unsigned int minor = MINOR(csdev->devt); |
@@ -336,7 +337,7 @@ static ssize_t show_read_buffer_kb(struct device *csdev, | |||
336 | return snprintf(buf, PAGE_SIZE, "%i\n", size); | 337 | return snprintf(buf, PAGE_SIZE, "%i\n", size); |
337 | } | 338 | } |
338 | 339 | ||
339 | static ssize_t store_read_buffer_kb(struct device *csdev, | 340 | static ssize_t read_buffer_kb_store(struct device *csdev, |
340 | struct device_attribute *attr, | 341 | struct device_attribute *attr, |
341 | const char *buf, size_t count) | 342 | const char *buf, size_t count) |
342 | { | 343 | { |
@@ -367,8 +368,9 @@ static ssize_t store_read_buffer_kb(struct device *csdev, | |||
367 | 368 | ||
368 | return err ? err : count; | 369 | return err ? err : count; |
369 | } | 370 | } |
371 | static DEVICE_ATTR_RW(read_buffer_kb); | ||
370 | 372 | ||
371 | static ssize_t show_max_write_buffer_kb(struct device *csdev, | 373 | static ssize_t max_write_buffer_kb_show(struct device *csdev, |
372 | struct device_attribute *attr, | 374 | struct device_attribute *attr, |
373 | char *buf) | 375 | char *buf) |
374 | { | 376 | { |
@@ -390,7 +392,7 @@ static ssize_t show_max_write_buffer_kb(struct device *csdev, | |||
390 | return snprintf(buf, PAGE_SIZE, "%i\n", size); | 392 | return snprintf(buf, PAGE_SIZE, "%i\n", size); |
391 | } | 393 | } |
392 | 394 | ||
393 | static ssize_t store_max_write_buffer_kb(struct device *csdev, | 395 | static ssize_t max_write_buffer_kb_store(struct device *csdev, |
394 | struct device_attribute *attr, | 396 | struct device_attribute *attr, |
395 | const char *buf, size_t count) | 397 | const char *buf, size_t count) |
396 | { | 398 | { |
@@ -421,8 +423,9 @@ static ssize_t store_max_write_buffer_kb(struct device *csdev, | |||
421 | 423 | ||
422 | return err ? err : count; | 424 | return err ? err : count; |
423 | } | 425 | } |
426 | static DEVICE_ATTR_RW(max_write_buffer_kb); | ||
424 | 427 | ||
425 | static ssize_t show_write_buffer_kb(struct device *csdev, | 428 | static ssize_t write_buffer_kb_show(struct device *csdev, |
426 | struct device_attribute *attr, char *buf) | 429 | struct device_attribute *attr, char *buf) |
427 | { | 430 | { |
428 | unsigned int minor = MINOR(csdev->devt); | 431 | unsigned int minor = MINOR(csdev->devt); |
@@ -443,7 +446,7 @@ static ssize_t show_write_buffer_kb(struct device *csdev, | |||
443 | return snprintf(buf, PAGE_SIZE, "%i\n", size); | 446 | return snprintf(buf, PAGE_SIZE, "%i\n", size); |
444 | } | 447 | } |
445 | 448 | ||
446 | static ssize_t store_write_buffer_kb(struct device *csdev, | 449 | static ssize_t write_buffer_kb_store(struct device *csdev, |
447 | struct device_attribute *attr, | 450 | struct device_attribute *attr, |
448 | const char *buf, size_t count) | 451 | const char *buf, size_t count) |
449 | { | 452 | { |
@@ -474,18 +477,16 @@ static ssize_t store_write_buffer_kb(struct device *csdev, | |||
474 | 477 | ||
475 | return err ? err : count; | 478 | return err ? err : count; |
476 | } | 479 | } |
480 | static DEVICE_ATTR_RW(write_buffer_kb); | ||
477 | 481 | ||
478 | static struct device_attribute comedi_dev_attrs[] = { | 482 | static struct attribute *comedi_dev_attrs[] = { |
479 | __ATTR(max_read_buffer_kb, S_IRUGO | S_IWUSR, | 483 | &dev_attr_max_read_buffer_kb.attr, |
480 | show_max_read_buffer_kb, store_max_read_buffer_kb), | 484 | &dev_attr_read_buffer_kb.attr, |
481 | __ATTR(read_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, | 485 | &dev_attr_max_write_buffer_kb.attr, |
482 | show_read_buffer_kb, store_read_buffer_kb), | 486 | &dev_attr_write_buffer_kb.attr, |
483 | __ATTR(max_write_buffer_kb, S_IRUGO | S_IWUSR, | 487 | NULL, |
484 | show_max_write_buffer_kb, store_max_write_buffer_kb), | ||
485 | __ATTR(write_buffer_kb, S_IRUGO | S_IWUSR | S_IWGRP, | ||
486 | show_write_buffer_kb, store_write_buffer_kb), | ||
487 | __ATTR_NULL | ||
488 | }; | 488 | }; |
489 | ATTRIBUTE_GROUPS(comedi_dev); | ||
489 | 490 | ||
490 | static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, | 491 | static void comedi_set_subdevice_runflags(struct comedi_subdevice *s, |
491 | unsigned mask, unsigned bits) | 492 | unsigned mask, unsigned bits) |
@@ -2564,7 +2565,7 @@ static int __init comedi_init(void) | |||
2564 | return PTR_ERR(comedi_class); | 2565 | return PTR_ERR(comedi_class); |
2565 | } | 2566 | } |
2566 | 2567 | ||
2567 | comedi_class->dev_attrs = comedi_dev_attrs; | 2568 | comedi_class->dev_groups = comedi_dev_groups; |
2568 | 2569 | ||
2569 | /* XXX requires /proc interface */ | 2570 | /* XXX requires /proc interface */ |
2570 | comedi_proc_init(); | 2571 | comedi_proc_init(); |
diff --git a/drivers/uio/uio.c b/drivers/uio/uio.c index 8abe78c0b16f..ba475632c5fa 100644 --- a/drivers/uio/uio.c +++ b/drivers/uio/uio.c | |||
@@ -223,38 +223,42 @@ static struct kobj_type portio_attr_type = { | |||
223 | .default_attrs = portio_attrs, | 223 | .default_attrs = portio_attrs, |
224 | }; | 224 | }; |
225 | 225 | ||
226 | static ssize_t show_name(struct device *dev, | 226 | static ssize_t name_show(struct device *dev, |
227 | struct device_attribute *attr, char *buf) | 227 | struct device_attribute *attr, char *buf) |
228 | { | 228 | { |
229 | struct uio_device *idev = dev_get_drvdata(dev); | 229 | struct uio_device *idev = dev_get_drvdata(dev); |
230 | return sprintf(buf, "%s\n", idev->info->name); | 230 | return sprintf(buf, "%s\n", idev->info->name); |
231 | } | 231 | } |
232 | static DEVICE_ATTR_RO(name); | ||
232 | 233 | ||
233 | static ssize_t show_version(struct device *dev, | 234 | static ssize_t version_show(struct device *dev, |
234 | struct device_attribute *attr, char *buf) | 235 | struct device_attribute *attr, char *buf) |
235 | { | 236 | { |
236 | struct uio_device *idev = dev_get_drvdata(dev); | 237 | struct uio_device *idev = dev_get_drvdata(dev); |
237 | return sprintf(buf, "%s\n", idev->info->version); | 238 | return sprintf(buf, "%s\n", idev->info->version); |
238 | } | 239 | } |
240 | static DEVICE_ATTR_RO(version); | ||
239 | 241 | ||
240 | static ssize_t show_event(struct device *dev, | 242 | static ssize_t event_show(struct device *dev, |
241 | struct device_attribute *attr, char *buf) | 243 | struct device_attribute *attr, char *buf) |
242 | { | 244 | { |
243 | struct uio_device *idev = dev_get_drvdata(dev); | 245 | struct uio_device *idev = dev_get_drvdata(dev); |
244 | return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event)); | 246 | return sprintf(buf, "%u\n", (unsigned int)atomic_read(&idev->event)); |
245 | } | 247 | } |
248 | static DEVICE_ATTR_RO(event); | ||
246 | 249 | ||
247 | static struct device_attribute uio_class_attributes[] = { | 250 | static struct attribute *uio_attrs[] = { |
248 | __ATTR(name, S_IRUGO, show_name, NULL), | 251 | &dev_attr_name.attr, |
249 | __ATTR(version, S_IRUGO, show_version, NULL), | 252 | &dev_attr_version.attr, |
250 | __ATTR(event, S_IRUGO, show_event, NULL), | 253 | &dev_attr_event.attr, |
251 | {} | 254 | NULL, |
252 | }; | 255 | }; |
256 | ATTRIBUTE_GROUPS(uio); | ||
253 | 257 | ||
254 | /* UIO class infrastructure */ | 258 | /* UIO class infrastructure */ |
255 | static struct class uio_class = { | 259 | static struct class uio_class = { |
256 | .name = "uio", | 260 | .name = "uio", |
257 | .dev_attrs = uio_class_attributes, | 261 | .dev_groups = uio_groups, |
258 | }; | 262 | }; |
259 | 263 | ||
260 | /* | 264 | /* |
diff --git a/drivers/usb/serial/bus.c b/drivers/usb/serial/bus.c index 0ce51f21ed2a..6335490d5760 100644 --- a/drivers/usb/serial/bus.c +++ b/drivers/usb/serial/bus.c | |||
@@ -121,7 +121,7 @@ static int usb_serial_device_remove(struct device *dev) | |||
121 | return retval; | 121 | return retval; |
122 | } | 122 | } |
123 | 123 | ||
124 | static ssize_t store_new_id(struct device_driver *driver, | 124 | static ssize_t new_id_store(struct device_driver *driver, |
125 | const char *buf, size_t count) | 125 | const char *buf, size_t count) |
126 | { | 126 | { |
127 | struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver); | 127 | 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, | |||
134 | return retval; | 134 | return retval; |
135 | } | 135 | } |
136 | 136 | ||
137 | static ssize_t show_dynids(struct device_driver *driver, char *buf) | 137 | static ssize_t new_id_show(struct device_driver *driver, char *buf) |
138 | { | 138 | { |
139 | struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver); | 139 | struct usb_serial_driver *usb_drv = to_usb_serial_driver(driver); |
140 | 140 | ||
141 | return usb_show_dynids(&usb_drv->dynids, buf); | 141 | return usb_show_dynids(&usb_drv->dynids, buf); |
142 | } | 142 | } |
143 | static DRIVER_ATTR_RW(new_id); | ||
143 | 144 | ||
144 | static struct driver_attribute drv_attrs[] = { | 145 | static struct attribute *usb_serial_drv_attrs[] = { |
145 | __ATTR(new_id, S_IRUGO | S_IWUSR, show_dynids, store_new_id), | 146 | &driver_attr_new_id.attr, |
146 | __ATTR_NULL, | 147 | NULL, |
147 | }; | 148 | }; |
149 | ATTRIBUTE_GROUPS(usb_serial_drv); | ||
148 | 150 | ||
149 | static void free_dynids(struct usb_serial_driver *drv) | 151 | static void free_dynids(struct usb_serial_driver *drv) |
150 | { | 152 | { |
@@ -163,7 +165,7 @@ struct bus_type usb_serial_bus_type = { | |||
163 | .match = usb_serial_device_match, | 165 | .match = usb_serial_device_match, |
164 | .probe = usb_serial_device_probe, | 166 | .probe = usb_serial_device_probe, |
165 | .remove = usb_serial_device_remove, | 167 | .remove = usb_serial_device_remove, |
166 | .drv_attrs = drv_attrs, | 168 | .drv_groups = usb_serial_drv_groups, |
167 | }; | 169 | }; |
168 | 170 | ||
169 | int usb_serial_bus_register(struct usb_serial_driver *driver) | 171 | int usb_serial_bus_register(struct usb_serial_driver *driver) |
diff --git a/drivers/video/backlight/backlight.c b/drivers/video/backlight/backlight.c index 3fccb6d3c8c3..94a403a9717a 100644 --- a/drivers/video/backlight/backlight.c +++ b/drivers/video/backlight/backlight.c | |||
@@ -103,16 +103,16 @@ static void backlight_generate_event(struct backlight_device *bd, | |||
103 | sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness"); | 103 | sysfs_notify(&bd->dev.kobj, NULL, "actual_brightness"); |
104 | } | 104 | } |
105 | 105 | ||
106 | static ssize_t backlight_show_power(struct device *dev, | 106 | static ssize_t bl_power_show(struct device *dev, struct device_attribute *attr, |
107 | struct device_attribute *attr, char *buf) | 107 | char *buf) |
108 | { | 108 | { |
109 | struct backlight_device *bd = to_backlight_device(dev); | 109 | struct backlight_device *bd = to_backlight_device(dev); |
110 | 110 | ||
111 | return sprintf(buf, "%d\n", bd->props.power); | 111 | return sprintf(buf, "%d\n", bd->props.power); |
112 | } | 112 | } |
113 | 113 | ||
114 | static ssize_t backlight_store_power(struct device *dev, | 114 | static ssize_t bl_power_store(struct device *dev, struct device_attribute *attr, |
115 | struct device_attribute *attr, const char *buf, size_t count) | 115 | const char *buf, size_t count) |
116 | { | 116 | { |
117 | int rc; | 117 | int rc; |
118 | struct backlight_device *bd = to_backlight_device(dev); | 118 | struct backlight_device *bd = to_backlight_device(dev); |
@@ -136,8 +136,9 @@ static ssize_t backlight_store_power(struct device *dev, | |||
136 | 136 | ||
137 | return rc; | 137 | return rc; |
138 | } | 138 | } |
139 | static DEVICE_ATTR_RW(bl_power); | ||
139 | 140 | ||
140 | static ssize_t backlight_show_brightness(struct device *dev, | 141 | static ssize_t brightness_show(struct device *dev, |
141 | struct device_attribute *attr, char *buf) | 142 | struct device_attribute *attr, char *buf) |
142 | { | 143 | { |
143 | struct backlight_device *bd = to_backlight_device(dev); | 144 | struct backlight_device *bd = to_backlight_device(dev); |
@@ -145,7 +146,7 @@ static ssize_t backlight_show_brightness(struct device *dev, | |||
145 | return sprintf(buf, "%d\n", bd->props.brightness); | 146 | return sprintf(buf, "%d\n", bd->props.brightness); |
146 | } | 147 | } |
147 | 148 | ||
148 | static ssize_t backlight_store_brightness(struct device *dev, | 149 | static ssize_t brightness_store(struct device *dev, |
149 | struct device_attribute *attr, const char *buf, size_t count) | 150 | struct device_attribute *attr, const char *buf, size_t count) |
150 | { | 151 | { |
151 | int rc; | 152 | int rc; |
@@ -175,24 +176,27 @@ static ssize_t backlight_store_brightness(struct device *dev, | |||
175 | 176 | ||
176 | return rc; | 177 | return rc; |
177 | } | 178 | } |
179 | static DEVICE_ATTR_RW(brightness); | ||
178 | 180 | ||
179 | static ssize_t backlight_show_type(struct device *dev, | 181 | static ssize_t type_show(struct device *dev, struct device_attribute *attr, |
180 | struct device_attribute *attr, char *buf) | 182 | char *buf) |
181 | { | 183 | { |
182 | struct backlight_device *bd = to_backlight_device(dev); | 184 | struct backlight_device *bd = to_backlight_device(dev); |
183 | 185 | ||
184 | return sprintf(buf, "%s\n", backlight_types[bd->props.type]); | 186 | return sprintf(buf, "%s\n", backlight_types[bd->props.type]); |
185 | } | 187 | } |
188 | static DEVICE_ATTR_RO(type); | ||
186 | 189 | ||
187 | static ssize_t backlight_show_max_brightness(struct device *dev, | 190 | static ssize_t max_brightness_show(struct device *dev, |
188 | struct device_attribute *attr, char *buf) | 191 | struct device_attribute *attr, char *buf) |
189 | { | 192 | { |
190 | struct backlight_device *bd = to_backlight_device(dev); | 193 | struct backlight_device *bd = to_backlight_device(dev); |
191 | 194 | ||
192 | return sprintf(buf, "%d\n", bd->props.max_brightness); | 195 | return sprintf(buf, "%d\n", bd->props.max_brightness); |
193 | } | 196 | } |
197 | static DEVICE_ATTR_RO(max_brightness); | ||
194 | 198 | ||
195 | static ssize_t backlight_show_actual_brightness(struct device *dev, | 199 | static ssize_t actual_brightness_show(struct device *dev, |
196 | struct device_attribute *attr, char *buf) | 200 | struct device_attribute *attr, char *buf) |
197 | { | 201 | { |
198 | int rc = -ENXIO; | 202 | int rc = -ENXIO; |
@@ -205,6 +209,7 @@ static ssize_t backlight_show_actual_brightness(struct device *dev, | |||
205 | 209 | ||
206 | return rc; | 210 | return rc; |
207 | } | 211 | } |
212 | static DEVICE_ATTR_RO(actual_brightness); | ||
208 | 213 | ||
209 | static struct class *backlight_class; | 214 | static struct class *backlight_class; |
210 | 215 | ||
@@ -247,16 +252,15 @@ static void bl_device_release(struct device *dev) | |||
247 | kfree(bd); | 252 | kfree(bd); |
248 | } | 253 | } |
249 | 254 | ||
250 | static struct device_attribute bl_device_attributes[] = { | 255 | static struct attribute *bl_device_attrs[] = { |
251 | __ATTR(bl_power, 0644, backlight_show_power, backlight_store_power), | 256 | &dev_attr_bl_power.attr, |
252 | __ATTR(brightness, 0644, backlight_show_brightness, | 257 | &dev_attr_brightness.attr, |
253 | backlight_store_brightness), | 258 | &dev_attr_actual_brightness.attr, |
254 | __ATTR(actual_brightness, 0444, backlight_show_actual_brightness, | 259 | &dev_attr_max_brightness.attr, |
255 | NULL), | 260 | &dev_attr_type.attr, |
256 | __ATTR(max_brightness, 0444, backlight_show_max_brightness, NULL), | 261 | NULL, |
257 | __ATTR(type, 0444, backlight_show_type, NULL), | ||
258 | __ATTR_NULL, | ||
259 | }; | 262 | }; |
263 | ATTRIBUTE_GROUPS(bl_device); | ||
260 | 264 | ||
261 | /** | 265 | /** |
262 | * backlight_force_update - tell the backlight subsystem that hardware state | 266 | * backlight_force_update - tell the backlight subsystem that hardware state |
@@ -493,7 +497,7 @@ static int __init backlight_class_init(void) | |||
493 | return PTR_ERR(backlight_class); | 497 | return PTR_ERR(backlight_class); |
494 | } | 498 | } |
495 | 499 | ||
496 | backlight_class->dev_attrs = bl_device_attributes; | 500 | backlight_class->dev_groups = bl_device_groups; |
497 | backlight_class->pm = &backlight_class_dev_pm_ops; | 501 | backlight_class->pm = &backlight_class_dev_pm_ops; |
498 | return 0; | 502 | return 0; |
499 | } | 503 | } |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index 41964a71a036..93cf15efc717 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -89,7 +89,7 @@ static inline void lcd_unregister_fb(struct lcd_device *ld) | |||
89 | } | 89 | } |
90 | #endif /* CONFIG_FB */ | 90 | #endif /* CONFIG_FB */ |
91 | 91 | ||
92 | static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr, | 92 | static ssize_t lcd_power_show(struct device *dev, struct device_attribute *attr, |
93 | char *buf) | 93 | char *buf) |
94 | { | 94 | { |
95 | int rc; | 95 | int rc; |
@@ -105,7 +105,7 @@ static ssize_t lcd_show_power(struct device *dev, struct device_attribute *attr, | |||
105 | return rc; | 105 | return rc; |
106 | } | 106 | } |
107 | 107 | ||
108 | static ssize_t lcd_store_power(struct device *dev, | 108 | static ssize_t lcd_power_store(struct device *dev, |
109 | struct device_attribute *attr, const char *buf, size_t count) | 109 | struct device_attribute *attr, const char *buf, size_t count) |
110 | { | 110 | { |
111 | int rc; | 111 | int rc; |
@@ -128,8 +128,9 @@ static ssize_t lcd_store_power(struct device *dev, | |||
128 | 128 | ||
129 | return rc; | 129 | return rc; |
130 | } | 130 | } |
131 | static DEVICE_ATTR_RW(lcd_power); | ||
131 | 132 | ||
132 | static ssize_t lcd_show_contrast(struct device *dev, | 133 | static ssize_t contrast_show(struct device *dev, |
133 | struct device_attribute *attr, char *buf) | 134 | struct device_attribute *attr, char *buf) |
134 | { | 135 | { |
135 | int rc = -ENXIO; | 136 | int rc = -ENXIO; |
@@ -143,7 +144,7 @@ static ssize_t lcd_show_contrast(struct device *dev, | |||
143 | return rc; | 144 | return rc; |
144 | } | 145 | } |
145 | 146 | ||
146 | static ssize_t lcd_store_contrast(struct device *dev, | 147 | static ssize_t contrast_store(struct device *dev, |
147 | struct device_attribute *attr, const char *buf, size_t count) | 148 | struct device_attribute *attr, const char *buf, size_t count) |
148 | { | 149 | { |
149 | int rc; | 150 | int rc; |
@@ -166,14 +167,16 @@ static ssize_t lcd_store_contrast(struct device *dev, | |||
166 | 167 | ||
167 | return rc; | 168 | return rc; |
168 | } | 169 | } |
170 | static DEVICE_ATTR_RW(contrast); | ||
169 | 171 | ||
170 | static ssize_t lcd_show_max_contrast(struct device *dev, | 172 | static ssize_t max_contrast_show(struct device *dev, |
171 | struct device_attribute *attr, char *buf) | 173 | struct device_attribute *attr, char *buf) |
172 | { | 174 | { |
173 | struct lcd_device *ld = to_lcd_device(dev); | 175 | struct lcd_device *ld = to_lcd_device(dev); |
174 | 176 | ||
175 | return sprintf(buf, "%d\n", ld->props.max_contrast); | 177 | return sprintf(buf, "%d\n", ld->props.max_contrast); |
176 | } | 178 | } |
179 | static DEVICE_ATTR_RO(max_contrast); | ||
177 | 180 | ||
178 | static struct class *lcd_class; | 181 | static struct class *lcd_class; |
179 | 182 | ||
@@ -183,12 +186,13 @@ static void lcd_device_release(struct device *dev) | |||
183 | kfree(ld); | 186 | kfree(ld); |
184 | } | 187 | } |
185 | 188 | ||
186 | static struct device_attribute lcd_device_attributes[] = { | 189 | static struct attribute *lcd_device_attrs[] = { |
187 | __ATTR(lcd_power, 0644, lcd_show_power, lcd_store_power), | 190 | &dev_attr_lcd_power.attr, |
188 | __ATTR(contrast, 0644, lcd_show_contrast, lcd_store_contrast), | 191 | &dev_attr_contrast.attr, |
189 | __ATTR(max_contrast, 0444, lcd_show_max_contrast, NULL), | 192 | &dev_attr_max_contrast.attr, |
190 | __ATTR_NULL, | 193 | NULL, |
191 | }; | 194 | }; |
195 | ATTRIBUTE_GROUPS(lcd_device); | ||
192 | 196 | ||
193 | /** | 197 | /** |
194 | * lcd_device_register - register a new object of lcd_device class. | 198 | * lcd_device_register - register a new object of lcd_device class. |
@@ -344,7 +348,7 @@ static int __init lcd_class_init(void) | |||
344 | return PTR_ERR(lcd_class); | 348 | return PTR_ERR(lcd_class); |
345 | } | 349 | } |
346 | 350 | ||
347 | lcd_class->dev_attrs = lcd_device_attributes; | 351 | lcd_class->dev_groups = lcd_device_groups; |
348 | return 0; | 352 | return 0; |
349 | } | 353 | } |
350 | 354 | ||
diff --git a/drivers/w1/slaves/w1_ds2408.c b/drivers/w1/slaves/w1_ds2408.c index cb8a8e5d9573..7dfa0e11688a 100644 --- a/drivers/w1/slaves/w1_ds2408.c +++ b/drivers/w1/slaves/w1_ds2408.c | |||
@@ -72,10 +72,9 @@ static int _read_reg(struct w1_slave *sl, u8 address, unsigned char* buf) | |||
72 | return 1; | 72 | return 1; |
73 | } | 73 | } |
74 | 74 | ||
75 | static ssize_t w1_f29_read_state( | 75 | static ssize_t state_read(struct file *filp, struct kobject *kobj, |
76 | struct file *filp, struct kobject *kobj, | 76 | struct bin_attribute *bin_attr, char *buf, loff_t off, |
77 | struct bin_attribute *bin_attr, | 77 | size_t count) |
78 | char *buf, loff_t off, size_t count) | ||
79 | { | 78 | { |
80 | dev_dbg(&kobj_to_w1_slave(kobj)->dev, | 79 | dev_dbg(&kobj_to_w1_slave(kobj)->dev, |
81 | "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", | 80 | "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", |
@@ -85,10 +84,9 @@ static ssize_t w1_f29_read_state( | |||
85 | return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf); | 84 | return _read_reg(kobj_to_w1_slave(kobj), W1_F29_REG_LOGIG_STATE, buf); |
86 | } | 85 | } |
87 | 86 | ||
88 | static ssize_t w1_f29_read_output( | 87 | static ssize_t output_read(struct file *filp, struct kobject *kobj, |
89 | struct file *filp, struct kobject *kobj, | 88 | struct bin_attribute *bin_attr, char *buf, |
90 | struct bin_attribute *bin_attr, | 89 | loff_t off, size_t count) |
91 | char *buf, loff_t off, size_t count) | ||
92 | { | 90 | { |
93 | dev_dbg(&kobj_to_w1_slave(kobj)->dev, | 91 | dev_dbg(&kobj_to_w1_slave(kobj)->dev, |
94 | "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", | 92 | "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", |
@@ -99,10 +97,9 @@ static ssize_t w1_f29_read_output( | |||
99 | W1_F29_REG_OUTPUT_LATCH_STATE, buf); | 97 | W1_F29_REG_OUTPUT_LATCH_STATE, buf); |
100 | } | 98 | } |
101 | 99 | ||
102 | static ssize_t w1_f29_read_activity( | 100 | static ssize_t activity_read(struct file *filp, struct kobject *kobj, |
103 | struct file *filp, struct kobject *kobj, | 101 | struct bin_attribute *bin_attr, char *buf, |
104 | struct bin_attribute *bin_attr, | 102 | loff_t off, size_t count) |
105 | char *buf, loff_t off, size_t count) | ||
106 | { | 103 | { |
107 | dev_dbg(&kobj_to_w1_slave(kobj)->dev, | 104 | dev_dbg(&kobj_to_w1_slave(kobj)->dev, |
108 | "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", | 105 | "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", |
@@ -113,10 +110,9 @@ static ssize_t w1_f29_read_activity( | |||
113 | W1_F29_REG_ACTIVITY_LATCH_STATE, buf); | 110 | W1_F29_REG_ACTIVITY_LATCH_STATE, buf); |
114 | } | 111 | } |
115 | 112 | ||
116 | static ssize_t w1_f29_read_cond_search_mask( | 113 | static ssize_t cond_search_mask_read(struct file *filp, struct kobject *kobj, |
117 | struct file *filp, struct kobject *kobj, | 114 | struct bin_attribute *bin_attr, char *buf, |
118 | struct bin_attribute *bin_attr, | 115 | loff_t off, size_t count) |
119 | char *buf, loff_t off, size_t count) | ||
120 | { | 116 | { |
121 | dev_dbg(&kobj_to_w1_slave(kobj)->dev, | 117 | dev_dbg(&kobj_to_w1_slave(kobj)->dev, |
122 | "Reading %s kobj: %p, off: %0#10x, count: %zu, buff addr: %p", | 118 | "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( | |||
127 | W1_F29_REG_COND_SEARCH_SELECT_MASK, buf); | 123 | W1_F29_REG_COND_SEARCH_SELECT_MASK, buf); |
128 | } | 124 | } |
129 | 125 | ||
130 | static ssize_t w1_f29_read_cond_search_polarity( | 126 | static ssize_t cond_search_polarity_read(struct file *filp, |
131 | struct file *filp, struct kobject *kobj, | 127 | struct kobject *kobj, |
132 | struct bin_attribute *bin_attr, | 128 | struct bin_attribute *bin_attr, |
133 | char *buf, loff_t off, size_t count) | 129 | char *buf, loff_t off, size_t count) |
134 | { | 130 | { |
135 | if (count != 1 || off != 0) | 131 | if (count != 1 || off != 0) |
136 | return -EFAULT; | 132 | return -EFAULT; |
@@ -138,10 +134,9 @@ static ssize_t w1_f29_read_cond_search_polarity( | |||
138 | W1_F29_REG_COND_SEARCH_POL_SELECT, buf); | 134 | W1_F29_REG_COND_SEARCH_POL_SELECT, buf); |
139 | } | 135 | } |
140 | 136 | ||
141 | static ssize_t w1_f29_read_status_control( | 137 | static ssize_t status_control_read(struct file *filp, struct kobject *kobj, |
142 | struct file *filp, struct kobject *kobj, | 138 | struct bin_attribute *bin_attr, char *buf, |
143 | struct bin_attribute *bin_attr, | 139 | loff_t off, size_t count) |
144 | char *buf, loff_t off, size_t count) | ||
145 | { | 140 | { |
146 | if (count != 1 || off != 0) | 141 | if (count != 1 || off != 0) |
147 | return -EFAULT; | 142 | return -EFAULT; |
@@ -149,13 +144,9 @@ static ssize_t w1_f29_read_status_control( | |||
149 | W1_F29_REG_CONTROL_AND_STATUS, buf); | 144 | W1_F29_REG_CONTROL_AND_STATUS, buf); |
150 | } | 145 | } |
151 | 146 | ||
152 | 147 | static ssize_t output_write(struct file *filp, struct kobject *kobj, | |
153 | 148 | struct bin_attribute *bin_attr, char *buf, | |
154 | 149 | loff_t off, size_t count) | |
155 | static ssize_t w1_f29_write_output( | ||
156 | struct file *filp, struct kobject *kobj, | ||
157 | struct bin_attribute *bin_attr, | ||
158 | char *buf, loff_t off, size_t count) | ||
159 | { | 150 | { |
160 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 151 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
161 | u8 w1_buf[3]; | 152 | u8 w1_buf[3]; |
@@ -224,10 +215,9 @@ error: | |||
224 | /** | 215 | /** |
225 | * Writing to the activity file resets the activity latches. | 216 | * Writing to the activity file resets the activity latches. |
226 | */ | 217 | */ |
227 | static ssize_t w1_f29_write_activity( | 218 | static ssize_t activity_write(struct file *filp, struct kobject *kobj, |
228 | struct file *filp, struct kobject *kobj, | 219 | struct bin_attribute *bin_attr, char *buf, |
229 | struct bin_attribute *bin_attr, | 220 | loff_t off, size_t count) |
230 | char *buf, loff_t off, size_t count) | ||
231 | { | 221 | { |
232 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 222 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
233 | unsigned int retries = W1_F29_RETRIES; | 223 | unsigned int retries = W1_F29_RETRIES; |
@@ -255,13 +245,9 @@ error: | |||
255 | return -EIO; | 245 | return -EIO; |
256 | } | 246 | } |
257 | 247 | ||
258 | static ssize_t w1_f29_write_status_control( | 248 | static ssize_t status_control_write(struct file *filp, struct kobject *kobj, |
259 | struct file *filp, | 249 | struct bin_attribute *bin_attr, char *buf, |
260 | struct kobject *kobj, | 250 | loff_t off, size_t count) |
261 | struct bin_attribute *bin_attr, | ||
262 | char *buf, | ||
263 | loff_t off, | ||
264 | size_t count) | ||
265 | { | 251 | { |
266 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 252 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
267 | u8 w1_buf[4]; | 253 | u8 w1_buf[4]; |
@@ -330,91 +316,35 @@ out: | |||
330 | return res; | 316 | return res; |
331 | } | 317 | } |
332 | 318 | ||
333 | static struct bin_attribute w1_f29_sysfs_bin_files[] = { | 319 | static BIN_ATTR_RO(state, 1); |
334 | { | 320 | static BIN_ATTR_RW(output, 1); |
335 | .attr = { | 321 | static BIN_ATTR_RW(activity, 1); |
336 | .name = "state", | 322 | static BIN_ATTR_RO(cond_search_mask, 1); |
337 | .mode = S_IRUGO, | 323 | static BIN_ATTR_RO(cond_search_polarity, 1); |
338 | }, | 324 | static BIN_ATTR_RW(status_control, 1); |
339 | .size = 1, | 325 | |
340 | .read = w1_f29_read_state, | 326 | static struct bin_attribute *w1_f29_bin_attrs[] = { |
341 | }, | 327 | &bin_attr_state, |
342 | { | 328 | &bin_attr_output, |
343 | .attr = { | 329 | &bin_attr_activity, |
344 | .name = "output", | 330 | &bin_attr_cond_search_mask, |
345 | .mode = S_IRUGO | S_IWUSR | S_IWGRP, | 331 | &bin_attr_cond_search_polarity, |
346 | }, | 332 | &bin_attr_status_control, |
347 | .size = 1, | 333 | NULL, |
348 | .read = w1_f29_read_output, | ||
349 | .write = w1_f29_write_output, | ||
350 | }, | ||
351 | { | ||
352 | .attr = { | ||
353 | .name = "activity", | ||
354 | .mode = S_IRUGO, | ||
355 | }, | ||
356 | .size = 1, | ||
357 | .read = w1_f29_read_activity, | ||
358 | .write = w1_f29_write_activity, | ||
359 | }, | ||
360 | { | ||
361 | .attr = { | ||
362 | .name = "cond_search_mask", | ||
363 | .mode = S_IRUGO, | ||
364 | }, | ||
365 | .size = 1, | ||
366 | .read = w1_f29_read_cond_search_mask, | ||
367 | }, | ||
368 | { | ||
369 | .attr = { | ||
370 | .name = "cond_search_polarity", | ||
371 | .mode = S_IRUGO, | ||
372 | }, | ||
373 | .size = 1, | ||
374 | .read = w1_f29_read_cond_search_polarity, | ||
375 | }, | ||
376 | { | ||
377 | .attr = { | ||
378 | .name = "status_control", | ||
379 | .mode = S_IRUGO | S_IWUSR | S_IWGRP, | ||
380 | }, | ||
381 | .size = 1, | ||
382 | .read = w1_f29_read_status_control, | ||
383 | .write = w1_f29_write_status_control, | ||
384 | } | ||
385 | }; | 334 | }; |
386 | 335 | ||
387 | static int w1_f29_add_slave(struct w1_slave *sl) | 336 | static const struct attribute_group w1_f29_group = { |
388 | { | 337 | .bin_attrs = w1_f29_bin_attrs, |
389 | int err = 0; | 338 | }; |
390 | int i; | ||
391 | |||
392 | err = w1_f29_disable_test_mode(sl); | ||
393 | if (err) | ||
394 | return err; | ||
395 | |||
396 | for (i = 0; i < ARRAY_SIZE(w1_f29_sysfs_bin_files) && !err; ++i) | ||
397 | err = sysfs_create_bin_file( | ||
398 | &sl->dev.kobj, | ||
399 | &(w1_f29_sysfs_bin_files[i])); | ||
400 | if (err) | ||
401 | while (--i >= 0) | ||
402 | sysfs_remove_bin_file(&sl->dev.kobj, | ||
403 | &(w1_f29_sysfs_bin_files[i])); | ||
404 | return err; | ||
405 | } | ||
406 | 339 | ||
407 | static void w1_f29_remove_slave(struct w1_slave *sl) | 340 | static const struct attribute_group *w1_f29_groups[] = { |
408 | { | 341 | &w1_f29_group, |
409 | int i; | 342 | NULL, |
410 | for (i = ARRAY_SIZE(w1_f29_sysfs_bin_files) - 1; i >= 0; --i) | 343 | }; |
411 | sysfs_remove_bin_file(&sl->dev.kobj, | ||
412 | &(w1_f29_sysfs_bin_files[i])); | ||
413 | } | ||
414 | 344 | ||
415 | static struct w1_family_ops w1_f29_fops = { | 345 | static struct w1_family_ops w1_f29_fops = { |
416 | .add_slave = w1_f29_add_slave, | 346 | .add_slave = w1_f29_disable_test_mode, |
417 | .remove_slave = w1_f29_remove_slave, | 347 | .groups = w1_f29_groups, |
418 | }; | 348 | }; |
419 | 349 | ||
420 | static struct w1_family w1_family_29 = { | 350 | static struct w1_family w1_family_29 = { |
diff --git a/drivers/w1/slaves/w1_ds2413.c b/drivers/w1/slaves/w1_ds2413.c index 85937773a96a..ee28fc1ff390 100644 --- a/drivers/w1/slaves/w1_ds2413.c +++ b/drivers/w1/slaves/w1_ds2413.c | |||
@@ -30,10 +30,9 @@ MODULE_ALIAS("w1-family-" __stringify(W1_FAMILY_DS2413)); | |||
30 | #define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A | 30 | #define W1_F3A_FUNC_PIO_ACCESS_WRITE 0x5A |
31 | #define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA | 31 | #define W1_F3A_SUCCESS_CONFIRM_BYTE 0xAA |
32 | 32 | ||
33 | static ssize_t w1_f3a_read_state( | 33 | static ssize_t state_read(struct file *filp, struct kobject *kobj, |
34 | struct file *filp, struct kobject *kobj, | 34 | struct bin_attribute *bin_attr, char *buf, loff_t off, |
35 | struct bin_attribute *bin_attr, | 35 | size_t count) |
36 | char *buf, loff_t off, size_t count) | ||
37 | { | 36 | { |
38 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 37 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
39 | dev_dbg(&sl->dev, | 38 | dev_dbg(&sl->dev, |
@@ -66,10 +65,11 @@ static ssize_t w1_f3a_read_state( | |||
66 | return 1; | 65 | return 1; |
67 | } | 66 | } |
68 | 67 | ||
69 | static ssize_t w1_f3a_write_output( | 68 | static BIN_ATTR_RO(state, 1); |
70 | struct file *filp, struct kobject *kobj, | 69 | |
71 | struct bin_attribute *bin_attr, | 70 | static ssize_t output_write(struct file *filp, struct kobject *kobj, |
72 | char *buf, loff_t off, size_t count) | 71 | struct bin_attribute *bin_attr, char *buf, |
72 | loff_t off, size_t count) | ||
73 | { | 73 | { |
74 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 74 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
75 | u8 w1_buf[3]; | 75 | u8 w1_buf[3]; |
@@ -110,53 +110,25 @@ error: | |||
110 | return -EIO; | 110 | return -EIO; |
111 | } | 111 | } |
112 | 112 | ||
113 | #define NB_SYSFS_BIN_FILES 2 | 113 | static BIN_ATTR(output, S_IRUGO | S_IWUSR | S_IWGRP, NULL, output_write, 1); |
114 | static struct bin_attribute w1_f3a_sysfs_bin_files[NB_SYSFS_BIN_FILES] = { | 114 | |
115 | { | 115 | static struct bin_attribute *w1_f3a_bin_attrs[] = { |
116 | .attr = { | 116 | &bin_attr_state, |
117 | .name = "state", | 117 | &bin_attr_output, |
118 | .mode = S_IRUGO, | 118 | NULL, |
119 | }, | ||
120 | .size = 1, | ||
121 | .read = w1_f3a_read_state, | ||
122 | }, | ||
123 | { | ||
124 | .attr = { | ||
125 | .name = "output", | ||
126 | .mode = S_IRUGO | S_IWUSR | S_IWGRP, | ||
127 | }, | ||
128 | .size = 1, | ||
129 | .write = w1_f3a_write_output, | ||
130 | } | ||
131 | }; | 119 | }; |
132 | 120 | ||
133 | static int w1_f3a_add_slave(struct w1_slave *sl) | 121 | static const struct attribute_group w1_f3a_group = { |
134 | { | 122 | .bin_attrs = w1_f3a_bin_attrs, |
135 | int err = 0; | 123 | }; |
136 | int i; | ||
137 | |||
138 | for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) | ||
139 | err = sysfs_create_bin_file( | ||
140 | &sl->dev.kobj, | ||
141 | &(w1_f3a_sysfs_bin_files[i])); | ||
142 | if (err) | ||
143 | while (--i >= 0) | ||
144 | sysfs_remove_bin_file(&sl->dev.kobj, | ||
145 | &(w1_f3a_sysfs_bin_files[i])); | ||
146 | return err; | ||
147 | } | ||
148 | 124 | ||
149 | static void w1_f3a_remove_slave(struct w1_slave *sl) | 125 | static const struct attribute_group *w1_f3a_groups[] = { |
150 | { | 126 | &w1_f3a_group, |
151 | int i; | 127 | NULL, |
152 | for (i = NB_SYSFS_BIN_FILES - 1; i >= 0; --i) | 128 | }; |
153 | sysfs_remove_bin_file(&sl->dev.kobj, | ||
154 | &(w1_f3a_sysfs_bin_files[i])); | ||
155 | } | ||
156 | 129 | ||
157 | static struct w1_family_ops w1_f3a_fops = { | 130 | static struct w1_family_ops w1_f3a_fops = { |
158 | .add_slave = w1_f3a_add_slave, | 131 | .groups = w1_f3a_groups, |
159 | .remove_slave = w1_f3a_remove_slave, | ||
160 | }; | 132 | }; |
161 | 133 | ||
162 | static struct w1_family w1_family_3a = { | 134 | static struct w1_family w1_family_3a = { |
diff --git a/drivers/w1/slaves/w1_ds2423.c b/drivers/w1/slaves/w1_ds2423.c index 7f86aec74088..7e41b7d91fb5 100644 --- a/drivers/w1/slaves/w1_ds2423.c +++ b/drivers/w1/slaves/w1_ds2423.c | |||
@@ -40,14 +40,8 @@ | |||
40 | #define COUNTER_COUNT 4 | 40 | #define COUNTER_COUNT 4 |
41 | #define READ_BYTE_COUNT 42 | 41 | #define READ_BYTE_COUNT 42 |
42 | 42 | ||
43 | static ssize_t w1_counter_read(struct device *device, | 43 | static ssize_t w1_slave_show(struct device *device, |
44 | struct device_attribute *attr, char *buf); | 44 | struct device_attribute *attr, char *out_buf) |
45 | |||
46 | static struct device_attribute w1_counter_attr = | ||
47 | __ATTR(w1_slave, S_IRUGO, w1_counter_read, NULL); | ||
48 | |||
49 | static ssize_t w1_counter_read(struct device *device, | ||
50 | struct device_attribute *attr, char *out_buf) | ||
51 | { | 45 | { |
52 | struct w1_slave *sl = dev_to_w1_slave(device); | 46 | struct w1_slave *sl = dev_to_w1_slave(device); |
53 | struct w1_master *dev = sl->master; | 47 | struct w1_master *dev = sl->master; |
@@ -128,19 +122,16 @@ static ssize_t w1_counter_read(struct device *device, | |||
128 | return PAGE_SIZE - c; | 122 | return PAGE_SIZE - c; |
129 | } | 123 | } |
130 | 124 | ||
131 | static int w1_f1d_add_slave(struct w1_slave *sl) | 125 | static DEVICE_ATTR_RO(w1_slave); |
132 | { | ||
133 | return device_create_file(&sl->dev, &w1_counter_attr); | ||
134 | } | ||
135 | 126 | ||
136 | static void w1_f1d_remove_slave(struct w1_slave *sl) | 127 | static struct attribute *w1_f1d_attrs[] = { |
137 | { | 128 | &dev_attr_w1_slave.attr, |
138 | device_remove_file(&sl->dev, &w1_counter_attr); | 129 | NULL, |
139 | } | 130 | }; |
131 | ATTRIBUTE_GROUPS(w1_f1d); | ||
140 | 132 | ||
141 | static struct w1_family_ops w1_f1d_fops = { | 133 | static struct w1_family_ops w1_f1d_fops = { |
142 | .add_slave = w1_f1d_add_slave, | 134 | .groups = w1_f1d_groups, |
143 | .remove_slave = w1_f1d_remove_slave, | ||
144 | }; | 135 | }; |
145 | 136 | ||
146 | static struct w1_family w1_family_1d = { | 137 | static struct w1_family w1_family_1d = { |
diff --git a/drivers/w1/slaves/w1_ds2431.c b/drivers/w1/slaves/w1_ds2431.c index cef8605e43ec..9c4ff9d28adc 100644 --- a/drivers/w1/slaves/w1_ds2431.c +++ b/drivers/w1/slaves/w1_ds2431.c | |||
@@ -96,9 +96,9 @@ static int w1_f2d_readblock(struct w1_slave *sl, int off, int count, char *buf) | |||
96 | return -1; | 96 | return -1; |
97 | } | 97 | } |
98 | 98 | ||
99 | static ssize_t w1_f2d_read_bin(struct file *filp, struct kobject *kobj, | 99 | static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, |
100 | struct bin_attribute *bin_attr, | 100 | struct bin_attribute *bin_attr, char *buf, |
101 | char *buf, loff_t off, size_t count) | 101 | loff_t off, size_t count) |
102 | { | 102 | { |
103 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 103 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
104 | int todo = count; | 104 | int todo = count; |
@@ -202,9 +202,9 @@ retry: | |||
202 | return 0; | 202 | return 0; |
203 | } | 203 | } |
204 | 204 | ||
205 | static ssize_t w1_f2d_write_bin(struct file *filp, struct kobject *kobj, | 205 | static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, |
206 | struct bin_attribute *bin_attr, | 206 | struct bin_attribute *bin_attr, char *buf, |
207 | char *buf, loff_t off, size_t count) | 207 | loff_t off, size_t count) |
208 | { | 208 | { |
209 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 209 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
210 | int addr, len; | 210 | int addr, len; |
@@ -264,29 +264,24 @@ out_up: | |||
264 | return count; | 264 | return count; |
265 | } | 265 | } |
266 | 266 | ||
267 | static struct bin_attribute w1_f2d_bin_attr = { | 267 | static BIN_ATTR_RW(eeprom, W1_F2D_EEPROM_SIZE); |
268 | .attr = { | 268 | |
269 | .name = "eeprom", | 269 | static struct bin_attribute *w1_f2d_bin_attrs[] = { |
270 | .mode = S_IRUGO | S_IWUSR, | 270 | &bin_attr_eeprom, |
271 | }, | 271 | NULL, |
272 | .size = W1_F2D_EEPROM_SIZE, | ||
273 | .read = w1_f2d_read_bin, | ||
274 | .write = w1_f2d_write_bin, | ||
275 | }; | 272 | }; |
276 | 273 | ||
277 | static int w1_f2d_add_slave(struct w1_slave *sl) | 274 | static const struct attribute_group w1_f2d_group = { |
278 | { | 275 | .bin_attrs = w1_f2d_bin_attrs, |
279 | return sysfs_create_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr); | 276 | }; |
280 | } | ||
281 | 277 | ||
282 | static void w1_f2d_remove_slave(struct w1_slave *sl) | 278 | static const struct attribute_group *w1_f2d_groups[] = { |
283 | { | 279 | &w1_f2d_group, |
284 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_f2d_bin_attr); | 280 | NULL, |
285 | } | 281 | }; |
286 | 282 | ||
287 | static struct w1_family_ops w1_f2d_fops = { | 283 | static struct w1_family_ops w1_f2d_fops = { |
288 | .add_slave = w1_f2d_add_slave, | 284 | .groups = w1_f2d_groups, |
289 | .remove_slave = w1_f2d_remove_slave, | ||
290 | }; | 285 | }; |
291 | 286 | ||
292 | static struct w1_family w1_family_2d = { | 287 | static struct w1_family w1_family_2d = { |
diff --git a/drivers/w1/slaves/w1_ds2433.c b/drivers/w1/slaves/w1_ds2433.c index 10cc1b6176e6..72319a968a9e 100644 --- a/drivers/w1/slaves/w1_ds2433.c +++ b/drivers/w1/slaves/w1_ds2433.c | |||
@@ -93,9 +93,9 @@ static int w1_f23_refresh_block(struct w1_slave *sl, struct w1_f23_data *data, | |||
93 | } | 93 | } |
94 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ | 94 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ |
95 | 95 | ||
96 | static ssize_t w1_f23_read_bin(struct file *filp, struct kobject *kobj, | 96 | static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, |
97 | struct bin_attribute *bin_attr, | 97 | struct bin_attribute *bin_attr, char *buf, |
98 | char *buf, loff_t off, size_t count) | 98 | loff_t off, size_t count) |
99 | { | 99 | { |
100 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 100 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
101 | #ifdef CONFIG_W1_SLAVE_DS2433_CRC | 101 | #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) | |||
207 | return 0; | 207 | return 0; |
208 | } | 208 | } |
209 | 209 | ||
210 | static ssize_t w1_f23_write_bin(struct file *filp, struct kobject *kobj, | 210 | static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, |
211 | struct bin_attribute *bin_attr, | 211 | struct bin_attribute *bin_attr, char *buf, |
212 | char *buf, loff_t off, size_t count) | 212 | loff_t off, size_t count) |
213 | { | 213 | { |
214 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 214 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
215 | int addr, len, idx; | 215 | int addr, len, idx; |
@@ -257,19 +257,24 @@ out_up: | |||
257 | return count; | 257 | return count; |
258 | } | 258 | } |
259 | 259 | ||
260 | static struct bin_attribute w1_f23_bin_attr = { | 260 | static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE); |
261 | .attr = { | 261 | |
262 | .name = "eeprom", | 262 | static struct bin_attribute *w1_f23_bin_attributes[] = { |
263 | .mode = S_IRUGO | S_IWUSR, | 263 | &bin_attr_eeprom, |
264 | }, | 264 | NULL, |
265 | .size = W1_EEPROM_SIZE, | 265 | }; |
266 | .read = w1_f23_read_bin, | 266 | |
267 | .write = w1_f23_write_bin, | 267 | static const struct attribute_group w1_f23_group = { |
268 | .bin_attrs = w1_f23_bin_attributes, | ||
269 | }; | ||
270 | |||
271 | static const struct attribute_group *w1_f23_groups[] = { | ||
272 | &w1_f23_group, | ||
273 | NULL, | ||
268 | }; | 274 | }; |
269 | 275 | ||
270 | static int w1_f23_add_slave(struct w1_slave *sl) | 276 | static int w1_f23_add_slave(struct w1_slave *sl) |
271 | { | 277 | { |
272 | int err; | ||
273 | #ifdef CONFIG_W1_SLAVE_DS2433_CRC | 278 | #ifdef CONFIG_W1_SLAVE_DS2433_CRC |
274 | struct w1_f23_data *data; | 279 | struct w1_f23_data *data; |
275 | 280 | ||
@@ -279,15 +284,7 @@ static int w1_f23_add_slave(struct w1_slave *sl) | |||
279 | sl->family_data = data; | 284 | sl->family_data = data; |
280 | 285 | ||
281 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ | 286 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ |
282 | 287 | return 0; | |
283 | err = sysfs_create_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); | ||
284 | |||
285 | #ifdef CONFIG_W1_SLAVE_DS2433_CRC | ||
286 | if (err) | ||
287 | kfree(data); | ||
288 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ | ||
289 | |||
290 | return err; | ||
291 | } | 288 | } |
292 | 289 | ||
293 | static void w1_f23_remove_slave(struct w1_slave *sl) | 290 | static void w1_f23_remove_slave(struct w1_slave *sl) |
@@ -296,12 +293,12 @@ static void w1_f23_remove_slave(struct w1_slave *sl) | |||
296 | kfree(sl->family_data); | 293 | kfree(sl->family_data); |
297 | sl->family_data = NULL; | 294 | sl->family_data = NULL; |
298 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ | 295 | #endif /* CONFIG_W1_SLAVE_DS2433_CRC */ |
299 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_f23_bin_attr); | ||
300 | } | 296 | } |
301 | 297 | ||
302 | static struct w1_family_ops w1_f23_fops = { | 298 | static struct w1_family_ops w1_f23_fops = { |
303 | .add_slave = w1_f23_add_slave, | 299 | .add_slave = w1_f23_add_slave, |
304 | .remove_slave = w1_f23_remove_slave, | 300 | .remove_slave = w1_f23_remove_slave, |
301 | .groups = w1_f23_groups, | ||
305 | }; | 302 | }; |
306 | 303 | ||
307 | static struct w1_family w1_family_23 = { | 304 | static struct w1_family w1_family_23 = { |
diff --git a/drivers/w1/slaves/w1_ds2760.c b/drivers/w1/slaves/w1_ds2760.c index 93719d25d849..65f90dccd60e 100644 --- a/drivers/w1/slaves/w1_ds2760.c +++ b/drivers/w1/slaves/w1_ds2760.c | |||
@@ -97,21 +97,28 @@ int w1_ds2760_recall_eeprom(struct device *dev, int addr) | |||
97 | return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); | 97 | return w1_ds2760_eeprom_cmd(dev, addr, W1_DS2760_RECALL_DATA); |
98 | } | 98 | } |
99 | 99 | ||
100 | static ssize_t w1_ds2760_read_bin(struct file *filp, struct kobject *kobj, | 100 | static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, |
101 | struct bin_attribute *bin_attr, | 101 | struct bin_attribute *bin_attr, char *buf, |
102 | char *buf, loff_t off, size_t count) | 102 | loff_t off, size_t count) |
103 | { | 103 | { |
104 | struct device *dev = container_of(kobj, struct device, kobj); | 104 | struct device *dev = container_of(kobj, struct device, kobj); |
105 | return w1_ds2760_read(dev, buf, off, count); | 105 | return w1_ds2760_read(dev, buf, off, count); |
106 | } | 106 | } |
107 | 107 | ||
108 | static struct bin_attribute w1_ds2760_bin_attr = { | 108 | static BIN_ATTR_RO(w1_slave, DS2760_DATA_SIZE); |
109 | .attr = { | 109 | |
110 | .name = "w1_slave", | 110 | static struct bin_attribute *w1_ds2760_bin_attrs[] = { |
111 | .mode = S_IRUGO, | 111 | &bin_attr_w1_slave, |
112 | }, | 112 | NULL, |
113 | .size = DS2760_DATA_SIZE, | 113 | }; |
114 | .read = w1_ds2760_read_bin, | 114 | |
115 | static const struct attribute_group w1_ds2760_group = { | ||
116 | .bin_attrs = w1_ds2760_bin_attrs, | ||
117 | }; | ||
118 | |||
119 | static const struct attribute_group *w1_ds2760_groups[] = { | ||
120 | &w1_ds2760_group, | ||
121 | NULL, | ||
115 | }; | 122 | }; |
116 | 123 | ||
117 | static DEFINE_IDA(bat_ida); | 124 | static DEFINE_IDA(bat_ida); |
@@ -139,16 +146,10 @@ static int w1_ds2760_add_slave(struct w1_slave *sl) | |||
139 | if (ret) | 146 | if (ret) |
140 | goto pdev_add_failed; | 147 | goto pdev_add_failed; |
141 | 148 | ||
142 | ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); | ||
143 | if (ret) | ||
144 | goto bin_attr_failed; | ||
145 | |||
146 | dev_set_drvdata(&sl->dev, pdev); | 149 | dev_set_drvdata(&sl->dev, pdev); |
147 | 150 | ||
148 | goto success; | 151 | goto success; |
149 | 152 | ||
150 | bin_attr_failed: | ||
151 | platform_device_del(pdev); | ||
152 | pdev_add_failed: | 153 | pdev_add_failed: |
153 | platform_device_put(pdev); | 154 | platform_device_put(pdev); |
154 | pdev_alloc_failed: | 155 | pdev_alloc_failed: |
@@ -165,12 +166,12 @@ static void w1_ds2760_remove_slave(struct w1_slave *sl) | |||
165 | 166 | ||
166 | platform_device_unregister(pdev); | 167 | platform_device_unregister(pdev); |
167 | ida_simple_remove(&bat_ida, id); | 168 | ida_simple_remove(&bat_ida, id); |
168 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2760_bin_attr); | ||
169 | } | 169 | } |
170 | 170 | ||
171 | static struct w1_family_ops w1_ds2760_fops = { | 171 | static struct w1_family_ops w1_ds2760_fops = { |
172 | .add_slave = w1_ds2760_add_slave, | 172 | .add_slave = w1_ds2760_add_slave, |
173 | .remove_slave = w1_ds2760_remove_slave, | 173 | .remove_slave = w1_ds2760_remove_slave, |
174 | .groups = w1_ds2760_groups, | ||
174 | }; | 175 | }; |
175 | 176 | ||
176 | static struct w1_family w1_ds2760_family = { | 177 | static struct w1_family w1_ds2760_family = { |
diff --git a/drivers/w1/slaves/w1_ds2780.c b/drivers/w1/slaves/w1_ds2780.c index 0cd7a27b5d6b..50e85f7929d4 100644 --- a/drivers/w1/slaves/w1_ds2780.c +++ b/drivers/w1/slaves/w1_ds2780.c | |||
@@ -89,22 +89,28 @@ int w1_ds2780_eeprom_cmd(struct device *dev, int addr, int cmd) | |||
89 | } | 89 | } |
90 | EXPORT_SYMBOL(w1_ds2780_eeprom_cmd); | 90 | EXPORT_SYMBOL(w1_ds2780_eeprom_cmd); |
91 | 91 | ||
92 | static ssize_t w1_ds2780_read_bin(struct file *filp, | 92 | static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, |
93 | struct kobject *kobj, | 93 | struct bin_attribute *bin_attr, char *buf, |
94 | struct bin_attribute *bin_attr, | 94 | loff_t off, size_t count) |
95 | char *buf, loff_t off, size_t count) | ||
96 | { | 95 | { |
97 | struct device *dev = container_of(kobj, struct device, kobj); | 96 | struct device *dev = container_of(kobj, struct device, kobj); |
98 | return w1_ds2780_io(dev, buf, off, count, 0); | 97 | return w1_ds2780_io(dev, buf, off, count, 0); |
99 | } | 98 | } |
100 | 99 | ||
101 | static struct bin_attribute w1_ds2780_bin_attr = { | 100 | static BIN_ATTR_RO(w1_slave, DS2780_DATA_SIZE); |
102 | .attr = { | 101 | |
103 | .name = "w1_slave", | 102 | static struct bin_attribute *w1_ds2780_bin_attrs[] = { |
104 | .mode = S_IRUGO, | 103 | &bin_attr_w1_slave, |
105 | }, | 104 | NULL, |
106 | .size = DS2780_DATA_SIZE, | 105 | }; |
107 | .read = w1_ds2780_read_bin, | 106 | |
107 | static const struct attribute_group w1_ds2780_group = { | ||
108 | .bin_attrs = w1_ds2780_bin_attrs, | ||
109 | }; | ||
110 | |||
111 | static const struct attribute_group *w1_ds2780_groups[] = { | ||
112 | &w1_ds2780_group, | ||
113 | NULL, | ||
108 | }; | 114 | }; |
109 | 115 | ||
110 | static DEFINE_IDA(bat_ida); | 116 | static DEFINE_IDA(bat_ida); |
@@ -132,16 +138,10 @@ static int w1_ds2780_add_slave(struct w1_slave *sl) | |||
132 | if (ret) | 138 | if (ret) |
133 | goto pdev_add_failed; | 139 | goto pdev_add_failed; |
134 | 140 | ||
135 | ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr); | ||
136 | if (ret) | ||
137 | goto bin_attr_failed; | ||
138 | |||
139 | dev_set_drvdata(&sl->dev, pdev); | 141 | dev_set_drvdata(&sl->dev, pdev); |
140 | 142 | ||
141 | return 0; | 143 | return 0; |
142 | 144 | ||
143 | bin_attr_failed: | ||
144 | platform_device_del(pdev); | ||
145 | pdev_add_failed: | 145 | pdev_add_failed: |
146 | platform_device_put(pdev); | 146 | platform_device_put(pdev); |
147 | pdev_alloc_failed: | 147 | pdev_alloc_failed: |
@@ -157,12 +157,12 @@ static void w1_ds2780_remove_slave(struct w1_slave *sl) | |||
157 | 157 | ||
158 | platform_device_unregister(pdev); | 158 | platform_device_unregister(pdev); |
159 | ida_simple_remove(&bat_ida, id); | 159 | ida_simple_remove(&bat_ida, id); |
160 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2780_bin_attr); | ||
161 | } | 160 | } |
162 | 161 | ||
163 | static struct w1_family_ops w1_ds2780_fops = { | 162 | static struct w1_family_ops w1_ds2780_fops = { |
164 | .add_slave = w1_ds2780_add_slave, | 163 | .add_slave = w1_ds2780_add_slave, |
165 | .remove_slave = w1_ds2780_remove_slave, | 164 | .remove_slave = w1_ds2780_remove_slave, |
165 | .groups = w1_ds2780_groups, | ||
166 | }; | 166 | }; |
167 | 167 | ||
168 | static struct w1_family w1_ds2780_family = { | 168 | static struct w1_family w1_ds2780_family = { |
diff --git a/drivers/w1/slaves/w1_ds2781.c b/drivers/w1/slaves/w1_ds2781.c index 1aba8e41ad46..1eb98fb1688d 100644 --- a/drivers/w1/slaves/w1_ds2781.c +++ b/drivers/w1/slaves/w1_ds2781.c | |||
@@ -87,22 +87,28 @@ int w1_ds2781_eeprom_cmd(struct device *dev, int addr, int cmd) | |||
87 | } | 87 | } |
88 | EXPORT_SYMBOL(w1_ds2781_eeprom_cmd); | 88 | EXPORT_SYMBOL(w1_ds2781_eeprom_cmd); |
89 | 89 | ||
90 | static ssize_t w1_ds2781_read_bin(struct file *filp, | 90 | static ssize_t w1_slave_read(struct file *filp, struct kobject *kobj, |
91 | struct kobject *kobj, | 91 | struct bin_attribute *bin_attr, char *buf, |
92 | struct bin_attribute *bin_attr, | 92 | loff_t off, size_t count) |
93 | char *buf, loff_t off, size_t count) | ||
94 | { | 93 | { |
95 | struct device *dev = container_of(kobj, struct device, kobj); | 94 | struct device *dev = container_of(kobj, struct device, kobj); |
96 | return w1_ds2781_io(dev, buf, off, count, 0); | 95 | return w1_ds2781_io(dev, buf, off, count, 0); |
97 | } | 96 | } |
98 | 97 | ||
99 | static struct bin_attribute w1_ds2781_bin_attr = { | 98 | static BIN_ATTR_RO(w1_slave, DS2781_DATA_SIZE); |
100 | .attr = { | 99 | |
101 | .name = "w1_slave", | 100 | static struct bin_attribute *w1_ds2781_bin_attrs[] = { |
102 | .mode = S_IRUGO, | 101 | &bin_attr_w1_slave, |
103 | }, | 102 | NULL, |
104 | .size = DS2781_DATA_SIZE, | 103 | }; |
105 | .read = w1_ds2781_read_bin, | 104 | |
105 | static const struct attribute_group w1_ds2781_group = { | ||
106 | .bin_attrs = w1_ds2781_bin_attrs, | ||
107 | }; | ||
108 | |||
109 | static const struct attribute_group *w1_ds2781_groups[] = { | ||
110 | &w1_ds2781_group, | ||
111 | NULL, | ||
106 | }; | 112 | }; |
107 | 113 | ||
108 | static DEFINE_IDA(bat_ida); | 114 | static DEFINE_IDA(bat_ida); |
@@ -130,16 +136,10 @@ static int w1_ds2781_add_slave(struct w1_slave *sl) | |||
130 | if (ret) | 136 | if (ret) |
131 | goto pdev_add_failed; | 137 | goto pdev_add_failed; |
132 | 138 | ||
133 | ret = sysfs_create_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr); | ||
134 | if (ret) | ||
135 | goto bin_attr_failed; | ||
136 | |||
137 | dev_set_drvdata(&sl->dev, pdev); | 139 | dev_set_drvdata(&sl->dev, pdev); |
138 | 140 | ||
139 | return 0; | 141 | return 0; |
140 | 142 | ||
141 | bin_attr_failed: | ||
142 | platform_device_del(pdev); | ||
143 | pdev_add_failed: | 143 | pdev_add_failed: |
144 | platform_device_put(pdev); | 144 | platform_device_put(pdev); |
145 | pdev_alloc_failed: | 145 | pdev_alloc_failed: |
@@ -155,12 +155,12 @@ static void w1_ds2781_remove_slave(struct w1_slave *sl) | |||
155 | 155 | ||
156 | platform_device_unregister(pdev); | 156 | platform_device_unregister(pdev); |
157 | ida_simple_remove(&bat_ida, id); | 157 | ida_simple_remove(&bat_ida, id); |
158 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_ds2781_bin_attr); | ||
159 | } | 158 | } |
160 | 159 | ||
161 | static struct w1_family_ops w1_ds2781_fops = { | 160 | static struct w1_family_ops w1_ds2781_fops = { |
162 | .add_slave = w1_ds2781_add_slave, | 161 | .add_slave = w1_ds2781_add_slave, |
163 | .remove_slave = w1_ds2781_remove_slave, | 162 | .remove_slave = w1_ds2781_remove_slave, |
163 | .groups = w1_ds2781_groups, | ||
164 | }; | 164 | }; |
165 | 165 | ||
166 | static struct w1_family w1_ds2781_family = { | 166 | static struct w1_family w1_ds2781_family = { |
diff --git a/drivers/w1/slaves/w1_ds28e04.c b/drivers/w1/slaves/w1_ds28e04.c index cd30a6d95ea5..365d6dff21de 100644 --- a/drivers/w1/slaves/w1_ds28e04.c +++ b/drivers/w1/slaves/w1_ds28e04.c | |||
@@ -118,9 +118,9 @@ static int w1_f1C_read(struct w1_slave *sl, int addr, int len, char *data) | |||
118 | return w1_read_block(sl->master, data, len); | 118 | return w1_read_block(sl->master, data, len); |
119 | } | 119 | } |
120 | 120 | ||
121 | static ssize_t w1_f1C_read_bin(struct file *filp, struct kobject *kobj, | 121 | static ssize_t eeprom_read(struct file *filp, struct kobject *kobj, |
122 | struct bin_attribute *bin_attr, | 122 | struct bin_attribute *bin_attr, char *buf, |
123 | char *buf, loff_t off, size_t count) | 123 | loff_t off, size_t count) |
124 | { | 124 | { |
125 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 125 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
126 | struct w1_f1C_data *data = sl->family_data; | 126 | 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) | |||
226 | return 0; | 226 | return 0; |
227 | } | 227 | } |
228 | 228 | ||
229 | static ssize_t w1_f1C_write_bin(struct file *filp, struct kobject *kobj, | 229 | static ssize_t eeprom_write(struct file *filp, struct kobject *kobj, |
230 | struct bin_attribute *bin_attr, | 230 | struct bin_attribute *bin_attr, char *buf, |
231 | char *buf, loff_t off, size_t count) | 231 | loff_t off, size_t count) |
232 | 232 | ||
233 | { | 233 | { |
234 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 234 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
@@ -280,9 +280,11 @@ out_up: | |||
280 | return count; | 280 | return count; |
281 | } | 281 | } |
282 | 282 | ||
283 | static ssize_t w1_f1C_read_pio(struct file *filp, struct kobject *kobj, | 283 | static BIN_ATTR_RW(eeprom, W1_EEPROM_SIZE); |
284 | struct bin_attribute *bin_attr, | 284 | |
285 | char *buf, loff_t off, size_t count) | 285 | static ssize_t pio_read(struct file *filp, struct kobject *kobj, |
286 | struct bin_attribute *bin_attr, char *buf, loff_t off, | ||
287 | size_t count) | ||
286 | 288 | ||
287 | { | 289 | { |
288 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 290 | 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, | |||
299 | return ret; | 301 | return ret; |
300 | } | 302 | } |
301 | 303 | ||
302 | static ssize_t w1_f1C_write_pio(struct file *filp, struct kobject *kobj, | 304 | static ssize_t pio_write(struct file *filp, struct kobject *kobj, |
303 | struct bin_attribute *bin_attr, | 305 | struct bin_attribute *bin_attr, char *buf, loff_t off, |
304 | char *buf, loff_t off, size_t count) | 306 | size_t count) |
305 | 307 | ||
306 | { | 308 | { |
307 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 309 | 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, | |||
339 | return count; | 341 | return count; |
340 | } | 342 | } |
341 | 343 | ||
342 | static ssize_t w1_f1C_show_crccheck(struct device *dev, | 344 | static BIN_ATTR_RW(pio, 1); |
343 | struct device_attribute *attr, char *buf) | 345 | |
346 | static ssize_t crccheck_show(struct device *dev, struct device_attribute *attr, | ||
347 | char *buf) | ||
344 | { | 348 | { |
345 | if (put_user(w1_enable_crccheck + 0x30, buf)) | 349 | if (put_user(w1_enable_crccheck + 0x30, buf)) |
346 | return -EFAULT; | 350 | return -EFAULT; |
@@ -348,9 +352,8 @@ static ssize_t w1_f1C_show_crccheck(struct device *dev, | |||
348 | return sizeof(w1_enable_crccheck); | 352 | return sizeof(w1_enable_crccheck); |
349 | } | 353 | } |
350 | 354 | ||
351 | static ssize_t w1_f1C_store_crccheck(struct device *dev, | 355 | static ssize_t crccheck_store(struct device *dev, struct device_attribute *attr, |
352 | struct device_attribute *attr, | 356 | const char *buf, size_t count) |
353 | const char *buf, size_t count) | ||
354 | { | 357 | { |
355 | char val; | 358 | char val; |
356 | 359 | ||
@@ -371,35 +374,31 @@ static ssize_t w1_f1C_store_crccheck(struct device *dev, | |||
371 | return sizeof(w1_enable_crccheck); | 374 | return sizeof(w1_enable_crccheck); |
372 | } | 375 | } |
373 | 376 | ||
374 | #define NB_SYSFS_BIN_FILES 2 | 377 | static DEVICE_ATTR_RW(crccheck); |
375 | static struct bin_attribute w1_f1C_bin_attr[NB_SYSFS_BIN_FILES] = { | 378 | |
376 | { | 379 | static struct attribute *w1_f1C_attrs[] = { |
377 | .attr = { | 380 | &dev_attr_crccheck.attr, |
378 | .name = "eeprom", | 381 | NULL, |
379 | .mode = S_IRUGO | S_IWUSR, | ||
380 | }, | ||
381 | .size = W1_EEPROM_SIZE, | ||
382 | .read = w1_f1C_read_bin, | ||
383 | .write = w1_f1C_write_bin, | ||
384 | }, | ||
385 | { | ||
386 | .attr = { | ||
387 | .name = "pio", | ||
388 | .mode = S_IRUGO | S_IWUSR, | ||
389 | }, | ||
390 | .size = 1, | ||
391 | .read = w1_f1C_read_pio, | ||
392 | .write = w1_f1C_write_pio, | ||
393 | } | ||
394 | }; | 382 | }; |
395 | 383 | ||
396 | static DEVICE_ATTR(crccheck, S_IWUSR | S_IRUGO, | 384 | static struct bin_attribute *w1_f1C_bin_attrs[] = { |
397 | w1_f1C_show_crccheck, w1_f1C_store_crccheck); | 385 | &bin_attr_eeprom, |
386 | &bin_attr_pio, | ||
387 | NULL, | ||
388 | }; | ||
389 | |||
390 | static const struct attribute_group w1_f1C_group = { | ||
391 | .attrs = w1_f1C_attrs, | ||
392 | .bin_attrs = w1_f1C_bin_attrs, | ||
393 | }; | ||
394 | |||
395 | static const struct attribute_group *w1_f1C_groups[] = { | ||
396 | &w1_f1C_group, | ||
397 | NULL, | ||
398 | }; | ||
398 | 399 | ||
399 | static int w1_f1C_add_slave(struct w1_slave *sl) | 400 | static int w1_f1C_add_slave(struct w1_slave *sl) |
400 | { | 401 | { |
401 | int err = 0; | ||
402 | int i; | ||
403 | struct w1_f1C_data *data = NULL; | 402 | struct w1_f1C_data *data = NULL; |
404 | 403 | ||
405 | if (w1_enable_crccheck) { | 404 | if (w1_enable_crccheck) { |
@@ -409,46 +408,19 @@ static int w1_f1C_add_slave(struct w1_slave *sl) | |||
409 | sl->family_data = data; | 408 | sl->family_data = data; |
410 | } | 409 | } |
411 | 410 | ||
412 | /* create binary sysfs attributes */ | 411 | return 0; |
413 | for (i = 0; i < NB_SYSFS_BIN_FILES && !err; ++i) | ||
414 | err = sysfs_create_bin_file( | ||
415 | &sl->dev.kobj, &(w1_f1C_bin_attr[i])); | ||
416 | |||
417 | if (!err) { | ||
418 | /* create device attributes */ | ||
419 | err = device_create_file(&sl->dev, &dev_attr_crccheck); | ||
420 | } | ||
421 | |||
422 | if (err) { | ||
423 | /* remove binary sysfs attributes */ | ||
424 | for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) | ||
425 | sysfs_remove_bin_file( | ||
426 | &sl->dev.kobj, &(w1_f1C_bin_attr[i])); | ||
427 | |||
428 | kfree(data); | ||
429 | } | ||
430 | |||
431 | return err; | ||
432 | } | 412 | } |
433 | 413 | ||
434 | static void w1_f1C_remove_slave(struct w1_slave *sl) | 414 | static void w1_f1C_remove_slave(struct w1_slave *sl) |
435 | { | 415 | { |
436 | int i; | ||
437 | |||
438 | kfree(sl->family_data); | 416 | kfree(sl->family_data); |
439 | sl->family_data = NULL; | 417 | sl->family_data = NULL; |
440 | |||
441 | /* remove device attributes */ | ||
442 | device_remove_file(&sl->dev, &dev_attr_crccheck); | ||
443 | |||
444 | /* remove binary sysfs attributes */ | ||
445 | for (i = 0; i < NB_SYSFS_BIN_FILES; ++i) | ||
446 | sysfs_remove_bin_file(&sl->dev.kobj, &(w1_f1C_bin_attr[i])); | ||
447 | } | 418 | } |
448 | 419 | ||
449 | static struct w1_family_ops w1_f1C_fops = { | 420 | static struct w1_family_ops w1_f1C_fops = { |
450 | .add_slave = w1_f1C_add_slave, | 421 | .add_slave = w1_f1C_add_slave, |
451 | .remove_slave = w1_f1C_remove_slave, | 422 | .remove_slave = w1_f1C_remove_slave, |
423 | .groups = w1_f1C_groups, | ||
452 | }; | 424 | }; |
453 | 425 | ||
454 | static struct w1_family w1_family_1C = { | 426 | static struct w1_family w1_family_1C = { |
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c index 8978360bd387..8b5ff33f72cf 100644 --- a/drivers/w1/slaves/w1_therm.c +++ b/drivers/w1/slaves/w1_therm.c | |||
@@ -59,25 +59,19 @@ static int w1_strong_pullup = 1; | |||
59 | module_param_named(strong_pullup, w1_strong_pullup, int, 0); | 59 | module_param_named(strong_pullup, w1_strong_pullup, int, 0); |
60 | 60 | ||
61 | 61 | ||
62 | static ssize_t w1_therm_read(struct device *device, | 62 | static ssize_t w1_slave_show(struct device *device, |
63 | struct device_attribute *attr, char *buf); | 63 | struct device_attribute *attr, char *buf); |
64 | 64 | ||
65 | static struct device_attribute w1_therm_attr = | 65 | static DEVICE_ATTR_RO(w1_slave); |
66 | __ATTR(w1_slave, S_IRUGO, w1_therm_read, NULL); | ||
67 | 66 | ||
68 | static int w1_therm_add_slave(struct w1_slave *sl) | 67 | static struct attribute *w1_therm_attrs[] = { |
69 | { | 68 | &dev_attr_w1_slave.attr, |
70 | return device_create_file(&sl->dev, &w1_therm_attr); | 69 | NULL, |
71 | } | 70 | }; |
72 | 71 | ATTRIBUTE_GROUPS(w1_therm); | |
73 | static void w1_therm_remove_slave(struct w1_slave *sl) | ||
74 | { | ||
75 | device_remove_file(&sl->dev, &w1_therm_attr); | ||
76 | } | ||
77 | 72 | ||
78 | static struct w1_family_ops w1_therm_fops = { | 73 | static struct w1_family_ops w1_therm_fops = { |
79 | .add_slave = w1_therm_add_slave, | 74 | .groups = w1_therm_groups, |
80 | .remove_slave = w1_therm_remove_slave, | ||
81 | }; | 75 | }; |
82 | 76 | ||
83 | static struct w1_family w1_therm_family_DS18S20 = { | 77 | static struct w1_family w1_therm_family_DS18S20 = { |
@@ -178,7 +172,7 @@ static inline int w1_convert_temp(u8 rom[9], u8 fid) | |||
178 | } | 172 | } |
179 | 173 | ||
180 | 174 | ||
181 | static ssize_t w1_therm_read(struct device *device, | 175 | static ssize_t w1_slave_show(struct device *device, |
182 | struct device_attribute *attr, char *buf) | 176 | struct device_attribute *attr, char *buf) |
183 | { | 177 | { |
184 | struct w1_slave *sl = dev_to_w1_slave(device); | 178 | struct w1_slave *sl = dev_to_w1_slave(device); |
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c index 0459df843c58..22013ca2119c 100644 --- a/drivers/w1/w1.c +++ b/drivers/w1/w1.c | |||
@@ -96,14 +96,15 @@ static void w1_slave_release(struct device *dev) | |||
96 | complete(&sl->released); | 96 | complete(&sl->released); |
97 | } | 97 | } |
98 | 98 | ||
99 | static ssize_t w1_slave_read_name(struct device *dev, struct device_attribute *attr, char *buf) | 99 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, char *buf) |
100 | { | 100 | { |
101 | struct w1_slave *sl = dev_to_w1_slave(dev); | 101 | struct w1_slave *sl = dev_to_w1_slave(dev); |
102 | 102 | ||
103 | return sprintf(buf, "%s\n", sl->name); | 103 | return sprintf(buf, "%s\n", sl->name); |
104 | } | 104 | } |
105 | static DEVICE_ATTR_RO(name); | ||
105 | 106 | ||
106 | static ssize_t w1_slave_read_id(struct device *dev, | 107 | static ssize_t id_show(struct device *dev, |
107 | struct device_attribute *attr, char *buf) | 108 | struct device_attribute *attr, char *buf) |
108 | { | 109 | { |
109 | struct w1_slave *sl = dev_to_w1_slave(dev); | 110 | struct w1_slave *sl = dev_to_w1_slave(dev); |
@@ -112,17 +113,20 @@ static ssize_t w1_slave_read_id(struct device *dev, | |||
112 | memcpy(buf, (u8 *)&sl->reg_num, count); | 113 | memcpy(buf, (u8 *)&sl->reg_num, count); |
113 | return count; | 114 | return count; |
114 | } | 115 | } |
116 | static DEVICE_ATTR_RO(id); | ||
115 | 117 | ||
116 | static struct device_attribute w1_slave_attr_name = | 118 | static struct attribute *w1_slave_attrs[] = { |
117 | __ATTR(name, S_IRUGO, w1_slave_read_name, NULL); | 119 | &dev_attr_name.attr, |
118 | static struct device_attribute w1_slave_attr_id = | 120 | &dev_attr_id.attr, |
119 | __ATTR(id, S_IRUGO, w1_slave_read_id, NULL); | 121 | NULL, |
122 | }; | ||
123 | ATTRIBUTE_GROUPS(w1_slave); | ||
120 | 124 | ||
121 | /* Default family */ | 125 | /* Default family */ |
122 | 126 | ||
123 | static ssize_t w1_default_write(struct file *filp, struct kobject *kobj, | 127 | static ssize_t rw_write(struct file *filp, struct kobject *kobj, |
124 | struct bin_attribute *bin_attr, | 128 | struct bin_attribute *bin_attr, char *buf, loff_t off, |
125 | char *buf, loff_t off, size_t count) | 129 | size_t count) |
126 | { | 130 | { |
127 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 131 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
128 | 132 | ||
@@ -139,9 +143,9 @@ out_up: | |||
139 | return count; | 143 | return count; |
140 | } | 144 | } |
141 | 145 | ||
142 | static ssize_t w1_default_read(struct file *filp, struct kobject *kobj, | 146 | static ssize_t rw_read(struct file *filp, struct kobject *kobj, |
143 | struct bin_attribute *bin_attr, | 147 | struct bin_attribute *bin_attr, char *buf, loff_t off, |
144 | char *buf, loff_t off, size_t count) | 148 | size_t count) |
145 | { | 149 | { |
146 | struct w1_slave *sl = kobj_to_w1_slave(kobj); | 150 | struct w1_slave *sl = kobj_to_w1_slave(kobj); |
147 | 151 | ||
@@ -151,29 +155,24 @@ static ssize_t w1_default_read(struct file *filp, struct kobject *kobj, | |||
151 | return count; | 155 | return count; |
152 | } | 156 | } |
153 | 157 | ||
154 | static struct bin_attribute w1_default_attr = { | 158 | static BIN_ATTR_RW(rw, PAGE_SIZE); |
155 | .attr = { | 159 | |
156 | .name = "rw", | 160 | static struct bin_attribute *w1_slave_bin_attrs[] = { |
157 | .mode = S_IRUGO | S_IWUSR, | 161 | &bin_attr_rw, |
158 | }, | 162 | NULL, |
159 | .size = PAGE_SIZE, | ||
160 | .read = w1_default_read, | ||
161 | .write = w1_default_write, | ||
162 | }; | 163 | }; |
163 | 164 | ||
164 | static int w1_default_add_slave(struct w1_slave *sl) | 165 | static const struct attribute_group w1_slave_default_group = { |
165 | { | 166 | .bin_attrs = w1_slave_bin_attrs, |
166 | return sysfs_create_bin_file(&sl->dev.kobj, &w1_default_attr); | 167 | }; |
167 | } | ||
168 | 168 | ||
169 | static void w1_default_remove_slave(struct w1_slave *sl) | 169 | static const struct attribute_group *w1_slave_default_groups[] = { |
170 | { | 170 | &w1_slave_default_group, |
171 | sysfs_remove_bin_file(&sl->dev.kobj, &w1_default_attr); | 171 | NULL, |
172 | } | 172 | }; |
173 | 173 | ||
174 | static struct w1_family_ops w1_default_fops = { | 174 | static struct w1_family_ops w1_default_fops = { |
175 | .add_slave = w1_default_add_slave, | 175 | .groups = w1_slave_default_groups, |
176 | .remove_slave = w1_default_remove_slave, | ||
177 | }; | 176 | }; |
178 | 177 | ||
179 | static struct w1_family w1_default_family = { | 178 | static struct w1_family w1_default_family = { |
@@ -587,6 +586,66 @@ end: | |||
587 | return err; | 586 | return err; |
588 | } | 587 | } |
589 | 588 | ||
589 | /* | ||
590 | * Handle sysfs file creation and removal here, before userspace is told that | ||
591 | * the device is added / removed from the system | ||
592 | */ | ||
593 | static int w1_bus_notify(struct notifier_block *nb, unsigned long action, | ||
594 | void *data) | ||
595 | { | ||
596 | struct device *dev = data; | ||
597 | struct w1_slave *sl; | ||
598 | struct w1_family_ops *fops; | ||
599 | int err; | ||
600 | |||
601 | /* | ||
602 | * Only care about slave devices at the moment. Yes, we should use a | ||
603 | * separate "type" for this, but for now, look at the release function | ||
604 | * to know which type it is... | ||
605 | */ | ||
606 | if (dev->release != w1_slave_release) | ||
607 | return 0; | ||
608 | |||
609 | sl = dev_to_w1_slave(dev); | ||
610 | fops = sl->family->fops; | ||
611 | |||
612 | switch (action) { | ||
613 | case BUS_NOTIFY_ADD_DEVICE: | ||
614 | /* if the family driver needs to initialize something... */ | ||
615 | if (fops->add_slave) { | ||
616 | err = fops->add_slave(sl); | ||
617 | if (err < 0) { | ||
618 | dev_err(&sl->dev, | ||
619 | "add_slave() call failed. err=%d\n", | ||
620 | err); | ||
621 | return err; | ||
622 | } | ||
623 | } | ||
624 | if (fops->groups) { | ||
625 | err = sysfs_create_groups(&sl->dev.kobj, fops->groups); | ||
626 | if (err) { | ||
627 | dev_err(&sl->dev, | ||
628 | "sysfs group creation failed. err=%d\n", | ||
629 | err); | ||
630 | return err; | ||
631 | } | ||
632 | } | ||
633 | |||
634 | break; | ||
635 | case BUS_NOTIFY_DEL_DEVICE: | ||
636 | if (fops->remove_slave) | ||
637 | sl->family->fops->remove_slave(sl); | ||
638 | if (fops->groups) | ||
639 | sysfs_remove_groups(&sl->dev.kobj, fops->groups); | ||
640 | break; | ||
641 | } | ||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | static struct notifier_block w1_bus_nb = { | ||
646 | .notifier_call = w1_bus_notify, | ||
647 | }; | ||
648 | |||
590 | static int __w1_attach_slave_device(struct w1_slave *sl) | 649 | static int __w1_attach_slave_device(struct w1_slave *sl) |
591 | { | 650 | { |
592 | int err; | 651 | int err; |
@@ -595,6 +654,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl) | |||
595 | sl->dev.driver = &w1_slave_driver; | 654 | sl->dev.driver = &w1_slave_driver; |
596 | sl->dev.bus = &w1_bus_type; | 655 | sl->dev.bus = &w1_bus_type; |
597 | sl->dev.release = &w1_slave_release; | 656 | sl->dev.release = &w1_slave_release; |
657 | sl->dev.groups = w1_slave_groups; | ||
598 | 658 | ||
599 | dev_set_name(&sl->dev, "%02x-%012llx", | 659 | dev_set_name(&sl->dev, "%02x-%012llx", |
600 | (unsigned int) sl->reg_num.family, | 660 | (unsigned int) sl->reg_num.family, |
@@ -615,44 +675,13 @@ static int __w1_attach_slave_device(struct w1_slave *sl) | |||
615 | return err; | 675 | return err; |
616 | } | 676 | } |
617 | 677 | ||
618 | /* Create "name" entry */ | ||
619 | err = device_create_file(&sl->dev, &w1_slave_attr_name); | ||
620 | if (err < 0) { | ||
621 | dev_err(&sl->dev, | ||
622 | "sysfs file creation for [%s] failed. err=%d\n", | ||
623 | dev_name(&sl->dev), err); | ||
624 | goto out_unreg; | ||
625 | } | ||
626 | |||
627 | /* Create "id" entry */ | ||
628 | err = device_create_file(&sl->dev, &w1_slave_attr_id); | ||
629 | if (err < 0) { | ||
630 | dev_err(&sl->dev, | ||
631 | "sysfs file creation for [%s] failed. err=%d\n", | ||
632 | dev_name(&sl->dev), err); | ||
633 | goto out_rem1; | ||
634 | } | ||
635 | 678 | ||
636 | /* if the family driver needs to initialize something... */ | 679 | dev_set_uevent_suppress(&sl->dev, false); |
637 | if (sl->family->fops && sl->family->fops->add_slave && | 680 | kobject_uevent(&sl->dev.kobj, KOBJ_ADD); |
638 | ((err = sl->family->fops->add_slave(sl)) < 0)) { | ||
639 | dev_err(&sl->dev, | ||
640 | "sysfs file creation for [%s] failed. err=%d\n", | ||
641 | dev_name(&sl->dev), err); | ||
642 | goto out_rem2; | ||
643 | } | ||
644 | 681 | ||
645 | list_add_tail(&sl->w1_slave_entry, &sl->master->slist); | 682 | list_add_tail(&sl->w1_slave_entry, &sl->master->slist); |
646 | 683 | ||
647 | return 0; | 684 | return 0; |
648 | |||
649 | out_rem2: | ||
650 | device_remove_file(&sl->dev, &w1_slave_attr_id); | ||
651 | out_rem1: | ||
652 | device_remove_file(&sl->dev, &w1_slave_attr_name); | ||
653 | out_unreg: | ||
654 | device_unregister(&sl->dev); | ||
655 | return err; | ||
656 | } | 685 | } |
657 | 686 | ||
658 | static int w1_attach_slave_device(struct w1_master *dev, struct w1_reg_num *rn) | 687 | 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) | |||
723 | 752 | ||
724 | list_del(&sl->w1_slave_entry); | 753 | list_del(&sl->w1_slave_entry); |
725 | 754 | ||
726 | if (sl->family->fops && sl->family->fops->remove_slave) | ||
727 | sl->family->fops->remove_slave(sl); | ||
728 | |||
729 | memset(&msg, 0, sizeof(msg)); | 755 | memset(&msg, 0, sizeof(msg)); |
730 | memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); | 756 | memcpy(msg.id.id, &sl->reg_num, sizeof(msg.id)); |
731 | msg.type = W1_SLAVE_REMOVE; | 757 | msg.type = W1_SLAVE_REMOVE; |
732 | w1_netlink_send(sl->master, &msg); | 758 | w1_netlink_send(sl->master, &msg); |
733 | 759 | ||
734 | device_remove_file(&sl->dev, &w1_slave_attr_id); | ||
735 | device_remove_file(&sl->dev, &w1_slave_attr_name); | ||
736 | device_unregister(&sl->dev); | 760 | device_unregister(&sl->dev); |
737 | 761 | ||
738 | wait_for_completion(&sl->released); | 762 | wait_for_completion(&sl->released); |
@@ -1017,6 +1041,10 @@ static int __init w1_init(void) | |||
1017 | goto err_out_exit_init; | 1041 | goto err_out_exit_init; |
1018 | } | 1042 | } |
1019 | 1043 | ||
1044 | retval = bus_register_notifier(&w1_bus_type, &w1_bus_nb); | ||
1045 | if (retval) | ||
1046 | goto err_out_bus_unregister; | ||
1047 | |||
1020 | retval = driver_register(&w1_master_driver); | 1048 | retval = driver_register(&w1_master_driver); |
1021 | if (retval) { | 1049 | if (retval) { |
1022 | printk(KERN_ERR | 1050 | printk(KERN_ERR |
diff --git a/drivers/w1/w1_family.h b/drivers/w1/w1_family.h index 625dd08f775f..4ad0e81b6404 100644 --- a/drivers/w1/w1_family.h +++ b/drivers/w1/w1_family.h | |||
@@ -52,6 +52,7 @@ struct w1_family_ops | |||
52 | { | 52 | { |
53 | int (* add_slave)(struct w1_slave *); | 53 | int (* add_slave)(struct w1_slave *); |
54 | void (* remove_slave)(struct w1_slave *); | 54 | void (* remove_slave)(struct w1_slave *); |
55 | const struct attribute_group **groups; | ||
55 | }; | 56 | }; |
56 | 57 | ||
57 | struct w1_family | 58 | struct w1_family |
diff --git a/fs/fuse/cuse.c b/fs/fuse/cuse.c index aef34b1e635e..adbfd66b380f 100644 --- a/fs/fuse/cuse.c +++ b/fs/fuse/cuse.c | |||
@@ -568,6 +568,7 @@ static ssize_t cuse_class_waiting_show(struct device *dev, | |||
568 | 568 | ||
569 | return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting)); | 569 | return sprintf(buf, "%d\n", atomic_read(&cc->fc.num_waiting)); |
570 | } | 570 | } |
571 | static DEVICE_ATTR(waiting, S_IFREG | 0400, cuse_class_waiting_show, NULL); | ||
571 | 572 | ||
572 | static ssize_t cuse_class_abort_store(struct device *dev, | 573 | static ssize_t cuse_class_abort_store(struct device *dev, |
573 | struct device_attribute *attr, | 574 | struct device_attribute *attr, |
@@ -578,12 +579,14 @@ static ssize_t cuse_class_abort_store(struct device *dev, | |||
578 | fuse_abort_conn(&cc->fc); | 579 | fuse_abort_conn(&cc->fc); |
579 | return count; | 580 | return count; |
580 | } | 581 | } |
582 | static DEVICE_ATTR(abort, S_IFREG | 0200, NULL, cuse_class_abort_store); | ||
581 | 583 | ||
582 | static struct device_attribute cuse_class_dev_attrs[] = { | 584 | static struct attribute *cuse_class_dev_attrs[] = { |
583 | __ATTR(waiting, S_IFREG | 0400, cuse_class_waiting_show, NULL), | 585 | &dev_attr_waiting.attr, |
584 | __ATTR(abort, S_IFREG | 0200, NULL, cuse_class_abort_store), | 586 | &dev_attr_abort.attr, |
585 | { } | 587 | NULL, |
586 | }; | 588 | }; |
589 | ATTRIBUTE_GROUPS(cuse_class_dev); | ||
587 | 590 | ||
588 | static struct miscdevice cuse_miscdev = { | 591 | static struct miscdevice cuse_miscdev = { |
589 | .minor = MISC_DYNAMIC_MINOR, | 592 | .minor = MISC_DYNAMIC_MINOR, |
@@ -609,7 +612,7 @@ static int __init cuse_init(void) | |||
609 | if (IS_ERR(cuse_class)) | 612 | if (IS_ERR(cuse_class)) |
610 | return PTR_ERR(cuse_class); | 613 | return PTR_ERR(cuse_class); |
611 | 614 | ||
612 | cuse_class->dev_attrs = cuse_class_dev_attrs; | 615 | cuse_class->dev_groups = cuse_class_dev_groups; |
613 | 616 | ||
614 | rc = misc_register(&cuse_miscdev); | 617 | rc = misc_register(&cuse_miscdev); |
615 | if (rc) { | 618 | if (rc) { |
diff --git a/fs/sysfs/bin.c b/fs/sysfs/bin.c index 15c68f9489ae..c590cabd57bb 100644 --- a/fs/sysfs/bin.c +++ b/fs/sysfs/bin.c | |||
@@ -22,8 +22,7 @@ | |||
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
24 | #include <linux/mm.h> | 24 | #include <linux/mm.h> |
25 | 25 | #include <linux/uaccess.h> | |
26 | #include <asm/uaccess.h> | ||
27 | 26 | ||
28 | #include "sysfs.h" | 27 | #include "sysfs.h" |
29 | 28 | ||
@@ -391,7 +390,7 @@ out_unlock: | |||
391 | return rc; | 390 | return rc; |
392 | } | 391 | } |
393 | 392 | ||
394 | static int open(struct inode * inode, struct file * file) | 393 | static int open(struct inode *inode, struct file *file) |
395 | { | 394 | { |
396 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; | 395 | struct sysfs_dirent *attr_sd = file->f_path.dentry->d_fsdata; |
397 | struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; | 396 | struct bin_attribute *attr = attr_sd->s_bin_attr.bin_attr; |
@@ -435,7 +434,7 @@ static int open(struct inode * inode, struct file * file) | |||
435 | return error; | 434 | return error; |
436 | } | 435 | } |
437 | 436 | ||
438 | static int release(struct inode * inode, struct file * file) | 437 | static int release(struct inode *inode, struct file *file) |
439 | { | 438 | { |
440 | struct bin_buffer *bb = file->private_data; | 439 | struct bin_buffer *bb = file->private_data; |
441 | 440 | ||
@@ -481,7 +480,6 @@ void unmap_bin_file(struct sysfs_dirent *attr_sd) | |||
481 | * @kobj: object. | 480 | * @kobj: object. |
482 | * @attr: attribute descriptor. | 481 | * @attr: attribute descriptor. |
483 | */ | 482 | */ |
484 | |||
485 | int sysfs_create_bin_file(struct kobject *kobj, | 483 | int sysfs_create_bin_file(struct kobject *kobj, |
486 | const struct bin_attribute *attr) | 484 | const struct bin_attribute *attr) |
487 | { | 485 | { |
@@ -489,19 +487,16 @@ int sysfs_create_bin_file(struct kobject *kobj, | |||
489 | 487 | ||
490 | return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR); | 488 | return sysfs_add_file(kobj->sd, &attr->attr, SYSFS_KOBJ_BIN_ATTR); |
491 | } | 489 | } |
492 | 490 | EXPORT_SYMBOL_GPL(sysfs_create_bin_file); | |
493 | 491 | ||
494 | /** | 492 | /** |
495 | * sysfs_remove_bin_file - remove binary file for object. | 493 | * sysfs_remove_bin_file - remove binary file for object. |
496 | * @kobj: object. | 494 | * @kobj: object. |
497 | * @attr: attribute descriptor. | 495 | * @attr: attribute descriptor. |
498 | */ | 496 | */ |
499 | |||
500 | void sysfs_remove_bin_file(struct kobject *kobj, | 497 | void sysfs_remove_bin_file(struct kobject *kobj, |
501 | const struct bin_attribute *attr) | 498 | const struct bin_attribute *attr) |
502 | { | 499 | { |
503 | sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name); | 500 | sysfs_hash_and_remove(kobj->sd, NULL, attr->attr.name); |
504 | } | 501 | } |
505 | |||
506 | EXPORT_SYMBOL_GPL(sysfs_create_bin_file); | ||
507 | EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); | 502 | EXPORT_SYMBOL_GPL(sysfs_remove_bin_file); |
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c index e068e744dbdd..99ec5b40e977 100644 --- a/fs/sysfs/dir.c +++ b/fs/sysfs/dir.c | |||
@@ -46,7 +46,7 @@ static unsigned int sysfs_name_hash(const void *ns, const char *name) | |||
46 | unsigned int len = strlen(name); | 46 | unsigned int len = strlen(name); |
47 | while (len--) | 47 | while (len--) |
48 | hash = partial_name_hash(*name++, hash); | 48 | hash = partial_name_hash(*name++, hash); |
49 | hash = ( end_name_hash(hash) ^ hash_ptr( (void *)ns, 31 ) ); | 49 | hash = (end_name_hash(hash) ^ hash_ptr((void *)ns, 31)); |
50 | hash &= 0x7fffffffU; | 50 | hash &= 0x7fffffffU; |
51 | /* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */ | 51 | /* Reserve hash numbers 0, 1 and INT_MAX for magic directory entries */ |
52 | if (hash < 1) | 52 | if (hash < 1) |
@@ -258,7 +258,7 @@ static void sysfs_free_ino(unsigned int ino) | |||
258 | spin_unlock(&sysfs_ino_lock); | 258 | spin_unlock(&sysfs_ino_lock); |
259 | } | 259 | } |
260 | 260 | ||
261 | void release_sysfs_dirent(struct sysfs_dirent * sd) | 261 | void release_sysfs_dirent(struct sysfs_dirent *sd) |
262 | { | 262 | { |
263 | struct sysfs_dirent *parent_sd; | 263 | struct sysfs_dirent *parent_sd; |
264 | 264 | ||
@@ -451,7 +451,7 @@ int __sysfs_add_one(struct sysfs_addrm_cxt *acxt, struct sysfs_dirent *sd) | |||
451 | 451 | ||
452 | if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) { | 452 | if (!!sysfs_ns_type(acxt->parent_sd) != !!sd->s_ns) { |
453 | WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", | 453 | WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", |
454 | sysfs_ns_type(acxt->parent_sd)? "required": "invalid", | 454 | sysfs_ns_type(acxt->parent_sd) ? "required" : "invalid", |
455 | acxt->parent_sd->s_name, sd->s_name); | 455 | acxt->parent_sd->s_name, sd->s_name); |
456 | return -EINVAL; | 456 | return -EINVAL; |
457 | } | 457 | } |
@@ -619,7 +619,7 @@ struct sysfs_dirent *sysfs_find_dirent(struct sysfs_dirent *parent_sd, | |||
619 | 619 | ||
620 | if (!!sysfs_ns_type(parent_sd) != !!ns) { | 620 | if (!!sysfs_ns_type(parent_sd) != !!ns) { |
621 | WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", | 621 | WARN(1, KERN_WARNING "sysfs: ns %s in '%s' for '%s'\n", |
622 | sysfs_ns_type(parent_sd)? "required": "invalid", | 622 | sysfs_ns_type(parent_sd) ? "required" : "invalid", |
623 | parent_sd->s_name, name); | 623 | parent_sd->s_name, name); |
624 | return NULL; | 624 | return NULL; |
625 | } | 625 | } |
@@ -674,7 +674,7 @@ static int create_dir(struct kobject *kobj, struct sysfs_dirent *parent_sd, | |||
674 | enum kobj_ns_type type, const void *ns, const char *name, | 674 | enum kobj_ns_type type, const void *ns, const char *name, |
675 | struct sysfs_dirent **p_sd) | 675 | struct sysfs_dirent **p_sd) |
676 | { | 676 | { |
677 | umode_t mode = S_IFDIR| S_IRWXU | S_IRUGO | S_IXUGO; | 677 | umode_t mode = S_IFDIR | S_IRWXU | S_IRUGO | S_IXUGO; |
678 | struct sysfs_addrm_cxt acxt; | 678 | struct sysfs_addrm_cxt acxt; |
679 | struct sysfs_dirent *sd; | 679 | struct sysfs_dirent *sd; |
680 | int rc; | 680 | int rc; |
@@ -735,9 +735,9 @@ static enum kobj_ns_type sysfs_read_ns_type(struct kobject *kobj) | |||
735 | 735 | ||
736 | /** | 736 | /** |
737 | * sysfs_create_dir - create a directory for an object. | 737 | * sysfs_create_dir - create a directory for an object. |
738 | * @kobj: object we're creating directory for. | 738 | * @kobj: object we're creating directory for. |
739 | */ | 739 | */ |
740 | int sysfs_create_dir(struct kobject * kobj) | 740 | int sysfs_create_dir(struct kobject *kobj) |
741 | { | 741 | { |
742 | enum kobj_ns_type type; | 742 | enum kobj_ns_type type; |
743 | struct sysfs_dirent *parent_sd, *sd; | 743 | struct sysfs_dirent *parent_sd, *sd; |
@@ -764,8 +764,8 @@ int sysfs_create_dir(struct kobject * kobj) | |||
764 | return error; | 764 | return error; |
765 | } | 765 | } |
766 | 766 | ||
767 | static struct dentry * sysfs_lookup(struct inode *dir, struct dentry *dentry, | 767 | static struct dentry *sysfs_lookup(struct inode *dir, struct dentry *dentry, |
768 | unsigned int flags) | 768 | unsigned int flags) |
769 | { | 769 | { |
770 | struct dentry *ret = NULL; | 770 | struct dentry *ret = NULL; |
771 | struct dentry *parent = dentry->d_parent; | 771 | struct dentry *parent = dentry->d_parent; |
@@ -857,7 +857,7 @@ static void __sysfs_remove_dir(struct sysfs_dirent *dir_sd) | |||
857 | * what used to be sysfs_rmdir() below, instead of calling separately. | 857 | * what used to be sysfs_rmdir() below, instead of calling separately. |
858 | */ | 858 | */ |
859 | 859 | ||
860 | void sysfs_remove_dir(struct kobject * kobj) | 860 | void sysfs_remove_dir(struct kobject *kobj) |
861 | { | 861 | { |
862 | struct sysfs_dirent *sd = kobj->sd; | 862 | struct sysfs_dirent *sd = kobj->sd; |
863 | 863 | ||
@@ -896,7 +896,9 @@ int sysfs_rename(struct sysfs_dirent *sd, | |||
896 | sd->s_name = new_name; | 896 | sd->s_name = new_name; |
897 | } | 897 | } |
898 | 898 | ||
899 | /* Move to the appropriate place in the appropriate directories rbtree. */ | 899 | /* |
900 | * Move to the appropriate place in the appropriate directories rbtree. | ||
901 | */ | ||
900 | sysfs_unlink_sibling(sd); | 902 | sysfs_unlink_sibling(sd); |
901 | sysfs_get(new_parent_sd); | 903 | sysfs_get(new_parent_sd); |
902 | sysfs_put(sd->s_parent); | 904 | sysfs_put(sd->s_parent); |
@@ -988,20 +990,21 @@ static struct sysfs_dirent *sysfs_dir_next_pos(const void *ns, | |||
988 | struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) | 990 | struct sysfs_dirent *parent_sd, ino_t ino, struct sysfs_dirent *pos) |
989 | { | 991 | { |
990 | pos = sysfs_dir_pos(ns, parent_sd, ino, pos); | 992 | pos = sysfs_dir_pos(ns, parent_sd, ino, pos); |
991 | if (pos) do { | 993 | if (pos) |
992 | struct rb_node *node = rb_next(&pos->s_rb); | 994 | do { |
993 | if (!node) | 995 | struct rb_node *node = rb_next(&pos->s_rb); |
994 | pos = NULL; | 996 | if (!node) |
995 | else | 997 | pos = NULL; |
996 | pos = to_sysfs_dirent(node); | 998 | else |
997 | } while (pos && pos->s_ns != ns); | 999 | pos = to_sysfs_dirent(node); |
1000 | } while (pos && pos->s_ns != ns); | ||
998 | return pos; | 1001 | return pos; |
999 | } | 1002 | } |
1000 | 1003 | ||
1001 | static int sysfs_readdir(struct file *file, struct dir_context *ctx) | 1004 | static int sysfs_readdir(struct file *file, struct dir_context *ctx) |
1002 | { | 1005 | { |
1003 | struct dentry *dentry = file->f_path.dentry; | 1006 | struct dentry *dentry = file->f_path.dentry; |
1004 | struct sysfs_dirent * parent_sd = dentry->d_fsdata; | 1007 | struct sysfs_dirent *parent_sd = dentry->d_fsdata; |
1005 | struct sysfs_dirent *pos = file->private_data; | 1008 | struct sysfs_dirent *pos = file->private_data; |
1006 | enum kobj_ns_type type; | 1009 | enum kobj_ns_type type; |
1007 | const void *ns; | 1010 | const void *ns; |
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c index d2bb7ed8fa74..15ef5eb13663 100644 --- a/fs/sysfs/file.c +++ b/fs/sysfs/file.c | |||
@@ -20,7 +20,7 @@ | |||
20 | #include <linux/list.h> | 20 | #include <linux/list.h> |
21 | #include <linux/mutex.h> | 21 | #include <linux/mutex.h> |
22 | #include <linux/limits.h> | 22 | #include <linux/limits.h> |
23 | #include <asm/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | 24 | ||
25 | #include "sysfs.h" | 25 | #include "sysfs.h" |
26 | 26 | ||
@@ -45,8 +45,8 @@ struct sysfs_open_dirent { | |||
45 | struct sysfs_buffer { | 45 | struct sysfs_buffer { |
46 | size_t count; | 46 | size_t count; |
47 | loff_t pos; | 47 | loff_t pos; |
48 | char * page; | 48 | char *page; |
49 | const struct sysfs_ops * ops; | 49 | const struct sysfs_ops *ops; |
50 | struct mutex mutex; | 50 | struct mutex mutex; |
51 | int needs_read_fill; | 51 | int needs_read_fill; |
52 | int event; | 52 | int event; |
@@ -59,16 +59,16 @@ struct sysfs_buffer { | |||
59 | * @buffer: data buffer for file. | 59 | * @buffer: data buffer for file. |
60 | * | 60 | * |
61 | * Allocate @buffer->page, if it hasn't been already, then call the | 61 | * Allocate @buffer->page, if it hasn't been already, then call the |
62 | * kobject's show() method to fill the buffer with this attribute's | 62 | * kobject's show() method to fill the buffer with this attribute's |
63 | * data. | 63 | * data. |
64 | * This is called only once, on the file's first read unless an error | 64 | * This is called only once, on the file's first read unless an error |
65 | * is returned. | 65 | * is returned. |
66 | */ | 66 | */ |
67 | static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer) | 67 | static int fill_read_buffer(struct dentry *dentry, struct sysfs_buffer *buffer) |
68 | { | 68 | { |
69 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 69 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; |
70 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 70 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; |
71 | const struct sysfs_ops * ops = buffer->ops; | 71 | const struct sysfs_ops *ops = buffer->ops; |
72 | int ret = 0; | 72 | int ret = 0; |
73 | ssize_t count; | 73 | ssize_t count; |
74 | 74 | ||
@@ -106,7 +106,7 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer | |||
106 | } | 106 | } |
107 | 107 | ||
108 | /** | 108 | /** |
109 | * sysfs_read_file - read an attribute. | 109 | * sysfs_read_file - read an attribute. |
110 | * @file: file pointer. | 110 | * @file: file pointer. |
111 | * @buf: buffer to fill. | 111 | * @buf: buffer to fill. |
112 | * @count: number of bytes to read. | 112 | * @count: number of bytes to read. |
@@ -127,12 +127,12 @@ static int fill_read_buffer(struct dentry * dentry, struct sysfs_buffer * buffer | |||
127 | static ssize_t | 127 | static ssize_t |
128 | sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) | 128 | sysfs_read_file(struct file *file, char __user *buf, size_t count, loff_t *ppos) |
129 | { | 129 | { |
130 | struct sysfs_buffer * buffer = file->private_data; | 130 | struct sysfs_buffer *buffer = file->private_data; |
131 | ssize_t retval = 0; | 131 | ssize_t retval = 0; |
132 | 132 | ||
133 | mutex_lock(&buffer->mutex); | 133 | mutex_lock(&buffer->mutex); |
134 | if (buffer->needs_read_fill || *ppos == 0) { | 134 | if (buffer->needs_read_fill || *ppos == 0) { |
135 | retval = fill_read_buffer(file->f_path.dentry,buffer); | 135 | retval = fill_read_buffer(file->f_path.dentry, buffer); |
136 | if (retval) | 136 | if (retval) |
137 | goto out; | 137 | goto out; |
138 | } | 138 | } |
@@ -154,9 +154,8 @@ out: | |||
154 | * Allocate @buffer->page if it hasn't been already, then | 154 | * Allocate @buffer->page if it hasn't been already, then |
155 | * copy the user-supplied buffer into it. | 155 | * copy the user-supplied buffer into it. |
156 | */ | 156 | */ |
157 | 157 | static int fill_write_buffer(struct sysfs_buffer *buffer, | |
158 | static int | 158 | const char __user *buf, size_t count) |
159 | fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t count) | ||
160 | { | 159 | { |
161 | int error; | 160 | int error; |
162 | 161 | ||
@@ -167,7 +166,7 @@ fill_write_buffer(struct sysfs_buffer * buffer, const char __user * buf, size_t | |||
167 | 166 | ||
168 | if (count >= PAGE_SIZE) | 167 | if (count >= PAGE_SIZE) |
169 | count = PAGE_SIZE - 1; | 168 | count = PAGE_SIZE - 1; |
170 | error = copy_from_user(buffer->page,buf,count); | 169 | error = copy_from_user(buffer->page, buf, count); |
171 | buffer->needs_read_fill = 1; | 170 | buffer->needs_read_fill = 1; |
172 | /* if buf is assumed to contain a string, terminate it by \0, | 171 | /* if buf is assumed to contain a string, terminate it by \0, |
173 | so e.g. sscanf() can scan the string easily */ | 172 | 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 | |||
183 | * @count: number of bytes | 182 | * @count: number of bytes |
184 | * | 183 | * |
185 | * Get the correct pointers for the kobject and the attribute we're | 184 | * Get the correct pointers for the kobject and the attribute we're |
186 | * dealing with, then call the store() method for the attribute, | 185 | * dealing with, then call the store() method for the attribute, |
187 | * passing the buffer that we acquired in fill_write_buffer(). | 186 | * passing the buffer that we acquired in fill_write_buffer(). |
188 | */ | 187 | */ |
189 | 188 | static int flush_write_buffer(struct dentry *dentry, | |
190 | static int | 189 | struct sysfs_buffer *buffer, size_t count) |
191 | flush_write_buffer(struct dentry * dentry, struct sysfs_buffer * buffer, size_t count) | ||
192 | { | 190 | { |
193 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; | 191 | struct sysfs_dirent *attr_sd = dentry->d_fsdata; |
194 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; | 192 | struct kobject *kobj = attr_sd->s_parent->s_dir.kobj; |
195 | const struct sysfs_ops * ops = buffer->ops; | 193 | const struct sysfs_ops *ops = buffer->ops; |
196 | int rc; | 194 | int rc; |
197 | 195 | ||
198 | /* need attr_sd for attr and ops, its parent for kobj */ | 196 | /* 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 | |||
219 | * then push it to the kobject in flush_write_buffer(). | 217 | * then push it to the kobject in flush_write_buffer(). |
220 | * There is no easy way for us to know if userspace is only doing a partial | 218 | * There is no easy way for us to know if userspace is only doing a partial |
221 | * write, so we don't support them. We expect the entire buffer to come | 219 | * write, so we don't support them. We expect the entire buffer to come |
222 | * on the first write. | 220 | * on the first write. |
223 | * Hint: if you're writing a value, first read the file, modify only the | 221 | * Hint: if you're writing a value, first read the file, modify only the |
224 | * the value you're changing, then write entire buffer back. | 222 | * the value you're changing, then write entire buffer back. |
225 | */ | 223 | */ |
226 | 224 | static ssize_t sysfs_write_file(struct file *file, const char __user *buf, | |
227 | static ssize_t | 225 | size_t count, loff_t *ppos) |
228 | sysfs_write_file(struct file *file, const char __user *buf, size_t count, loff_t *ppos) | ||
229 | { | 226 | { |
230 | struct sysfs_buffer * buffer = file->private_data; | 227 | struct sysfs_buffer *buffer = file->private_data; |
231 | ssize_t len; | 228 | ssize_t len; |
232 | 229 | ||
233 | mutex_lock(&buffer->mutex); | 230 | mutex_lock(&buffer->mutex); |
@@ -339,13 +336,14 @@ static int sysfs_open_file(struct inode *inode, struct file *file) | |||
339 | if (kobj->ktype && kobj->ktype->sysfs_ops) | 336 | if (kobj->ktype && kobj->ktype->sysfs_ops) |
340 | ops = kobj->ktype->sysfs_ops; | 337 | ops = kobj->ktype->sysfs_ops; |
341 | else { | 338 | else { |
342 | WARN(1, KERN_ERR "missing sysfs attribute operations for " | 339 | WARN(1, KERN_ERR |
343 | "kobject: %s\n", kobject_name(kobj)); | 340 | "missing sysfs attribute operations for kobject: %s\n", |
341 | kobject_name(kobj)); | ||
344 | goto err_out; | 342 | goto err_out; |
345 | } | 343 | } |
346 | 344 | ||
347 | /* File needs write support. | 345 | /* File needs write support. |
348 | * The inode's perms must say it's ok, | 346 | * The inode's perms must say it's ok, |
349 | * and we must have a store method. | 347 | * and we must have a store method. |
350 | */ | 348 | */ |
351 | if (file->f_mode & FMODE_WRITE) { | 349 | if (file->f_mode & FMODE_WRITE) { |
@@ -420,7 +418,7 @@ static int sysfs_release(struct inode *inode, struct file *filp) | |||
420 | */ | 418 | */ |
421 | static unsigned int sysfs_poll(struct file *filp, poll_table *wait) | 419 | static unsigned int sysfs_poll(struct file *filp, poll_table *wait) |
422 | { | 420 | { |
423 | struct sysfs_buffer * buffer = filp->private_data; | 421 | struct sysfs_buffer *buffer = filp->private_data; |
424 | struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; | 422 | struct sysfs_dirent *attr_sd = filp->f_path.dentry->d_fsdata; |
425 | struct sysfs_open_dirent *od = attr_sd->s_attr.open; | 423 | struct sysfs_open_dirent *od = attr_sd->s_attr.open; |
426 | 424 | ||
@@ -518,8 +516,9 @@ static int sysfs_attr_ns(struct kobject *kobj, const struct attribute *attr, | |||
518 | ns = ops->namespace(kobj, attr); | 516 | ns = ops->namespace(kobj, attr); |
519 | out: | 517 | out: |
520 | if (err) { | 518 | if (err) { |
521 | WARN(1, KERN_ERR "missing sysfs namespace attribute operation for " | 519 | WARN(1, KERN_ERR |
522 | "kobject: %s\n", kobject_name(kobj)); | 520 | "missing sysfs namespace attribute operation for kobject: %s\n", |
521 | kobject_name(kobj)); | ||
523 | } | 522 | } |
524 | *pns = ns; | 523 | *pns = ns; |
525 | return err; | 524 | return err; |
@@ -566,17 +565,17 @@ int sysfs_add_file(struct sysfs_dirent *dir_sd, const struct attribute *attr, | |||
566 | 565 | ||
567 | /** | 566 | /** |
568 | * sysfs_create_file - create an attribute file for an object. | 567 | * sysfs_create_file - create an attribute file for an object. |
569 | * @kobj: object we're creating for. | 568 | * @kobj: object we're creating for. |
570 | * @attr: attribute descriptor. | 569 | * @attr: attribute descriptor. |
571 | */ | 570 | */ |
572 | 571 | int sysfs_create_file(struct kobject *kobj, const struct attribute *attr) | |
573 | int sysfs_create_file(struct kobject * kobj, const struct attribute * attr) | ||
574 | { | 572 | { |
575 | BUG_ON(!kobj || !kobj->sd || !attr); | 573 | BUG_ON(!kobj || !kobj->sd || !attr); |
576 | 574 | ||
577 | return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR); | 575 | return sysfs_add_file(kobj->sd, attr, SYSFS_KOBJ_ATTR); |
578 | 576 | ||
579 | } | 577 | } |
578 | EXPORT_SYMBOL_GPL(sysfs_create_file); | ||
580 | 579 | ||
581 | int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) | 580 | int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) |
582 | { | 581 | { |
@@ -590,6 +589,7 @@ int sysfs_create_files(struct kobject *kobj, const struct attribute **ptr) | |||
590 | sysfs_remove_file(kobj, ptr[i]); | 589 | sysfs_remove_file(kobj, ptr[i]); |
591 | return err; | 590 | return err; |
592 | } | 591 | } |
592 | EXPORT_SYMBOL_GPL(sysfs_create_files); | ||
593 | 593 | ||
594 | /** | 594 | /** |
595 | * sysfs_add_file_to_group - add an attribute file to a pre-existing group. | 595 | * 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, | |||
654 | } | 654 | } |
655 | EXPORT_SYMBOL_GPL(sysfs_chmod_file); | 655 | EXPORT_SYMBOL_GPL(sysfs_chmod_file); |
656 | 656 | ||
657 | |||
658 | /** | 657 | /** |
659 | * sysfs_remove_file - remove an object attribute. | 658 | * sysfs_remove_file - remove an object attribute. |
660 | * @kobj: object we're acting for. | 659 | * @kobj: object we're acting for. |
@@ -662,8 +661,7 @@ EXPORT_SYMBOL_GPL(sysfs_chmod_file); | |||
662 | * | 661 | * |
663 | * Hash the attribute name and kill the victim. | 662 | * Hash the attribute name and kill the victim. |
664 | */ | 663 | */ |
665 | 664 | void sysfs_remove_file(struct kobject *kobj, const struct attribute *attr) | |
666 | void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) | ||
667 | { | 665 | { |
668 | const void *ns; | 666 | const void *ns; |
669 | 667 | ||
@@ -672,13 +670,15 @@ void sysfs_remove_file(struct kobject * kobj, const struct attribute * attr) | |||
672 | 670 | ||
673 | sysfs_hash_and_remove(kobj->sd, ns, attr->name); | 671 | sysfs_hash_and_remove(kobj->sd, ns, attr->name); |
674 | } | 672 | } |
673 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | ||
675 | 674 | ||
676 | void sysfs_remove_files(struct kobject * kobj, const struct attribute **ptr) | 675 | void sysfs_remove_files(struct kobject *kobj, const struct attribute **ptr) |
677 | { | 676 | { |
678 | int i; | 677 | int i; |
679 | for (i = 0; ptr[i]; i++) | 678 | for (i = 0; ptr[i]; i++) |
680 | sysfs_remove_file(kobj, ptr[i]); | 679 | sysfs_remove_file(kobj, ptr[i]); |
681 | } | 680 | } |
681 | EXPORT_SYMBOL_GPL(sysfs_remove_files); | ||
682 | 682 | ||
683 | /** | 683 | /** |
684 | * sysfs_remove_file_from_group - remove an attribute file from a group. | 684 | * 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 *), | |||
793 | return 0; | 793 | return 0; |
794 | } | 794 | } |
795 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); | 795 | EXPORT_SYMBOL_GPL(sysfs_schedule_callback); |
796 | |||
797 | |||
798 | EXPORT_SYMBOL_GPL(sysfs_create_file); | ||
799 | EXPORT_SYMBOL_GPL(sysfs_remove_file); | ||
800 | EXPORT_SYMBOL_GPL(sysfs_remove_files); | ||
801 | EXPORT_SYMBOL_GPL(sysfs_create_files); | ||
diff --git a/fs/sysfs/group.c b/fs/sysfs/group.c index 09a1a25cd145..5f92cd2f61c1 100644 --- a/fs/sysfs/group.c +++ b/fs/sysfs/group.c | |||
@@ -3,8 +3,10 @@ | |||
3 | * | 3 | * |
4 | * Copyright (c) 2003 Patrick Mochel | 4 | * Copyright (c) 2003 Patrick Mochel |
5 | * Copyright (c) 2003 Open Source Development Lab | 5 | * Copyright (c) 2003 Open Source Development Lab |
6 | * Copyright (c) 2013 Greg Kroah-Hartman | ||
7 | * Copyright (c) 2013 The Linux Foundation | ||
6 | * | 8 | * |
7 | * This file is released undert the GPL v2. | 9 | * This file is released undert the GPL v2. |
8 | * | 10 | * |
9 | */ | 11 | */ |
10 | 12 | ||
@@ -19,8 +21,8 @@ | |||
19 | static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 21 | static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, |
20 | const struct attribute_group *grp) | 22 | const struct attribute_group *grp) |
21 | { | 23 | { |
22 | struct attribute *const* attr; | 24 | struct attribute *const *attr; |
23 | struct bin_attribute *const* bin_attr; | 25 | struct bin_attribute *const *bin_attr; |
24 | 26 | ||
25 | if (grp->attrs) | 27 | if (grp->attrs) |
26 | for (attr = grp->attrs; *attr; attr++) | 28 | for (attr = grp->attrs; *attr; attr++) |
@@ -33,8 +35,8 @@ static void remove_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | |||
33 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, | 35 | static int create_files(struct sysfs_dirent *dir_sd, struct kobject *kobj, |
34 | const struct attribute_group *grp, int update) | 36 | const struct attribute_group *grp, int update) |
35 | { | 37 | { |
36 | struct attribute *const* attr; | 38 | struct attribute *const *attr; |
37 | struct bin_attribute *const* bin_attr; | 39 | struct bin_attribute *const *bin_attr; |
38 | int error = 0, i; | 40 | int error = 0, i; |
39 | 41 | ||
40 | if (grp->attrs) { | 42 | if (grp->attrs) { |
@@ -129,6 +131,41 @@ int sysfs_create_group(struct kobject *kobj, | |||
129 | { | 131 | { |
130 | return internal_create_group(kobj, 0, grp); | 132 | return internal_create_group(kobj, 0, grp); |
131 | } | 133 | } |
134 | EXPORT_SYMBOL_GPL(sysfs_create_group); | ||
135 | |||
136 | /** | ||
137 | * sysfs_create_groups - given a directory kobject, create a bunch of attribute groups | ||
138 | * @kobj: The kobject to create the group on | ||
139 | * @groups: The attribute groups to create, NULL terminated | ||
140 | * | ||
141 | * This function creates a bunch of attribute groups. If an error occurs when | ||
142 | * creating a group, all previously created groups will be removed, unwinding | ||
143 | * everything back to the original state when this function was called. | ||
144 | * It will explicitly warn and error if any of the attribute files being | ||
145 | * created already exist. | ||
146 | * | ||
147 | * Returns 0 on success or error code from sysfs_create_group on error. | ||
148 | */ | ||
149 | int sysfs_create_groups(struct kobject *kobj, | ||
150 | const struct attribute_group **groups) | ||
151 | { | ||
152 | int error = 0; | ||
153 | int i; | ||
154 | |||
155 | if (!groups) | ||
156 | return 0; | ||
157 | |||
158 | for (i = 0; groups[i]; i++) { | ||
159 | error = sysfs_create_group(kobj, groups[i]); | ||
160 | if (error) { | ||
161 | while (--i >= 0) | ||
162 | sysfs_remove_group(kobj, groups[i]); | ||
163 | break; | ||
164 | } | ||
165 | } | ||
166 | return error; | ||
167 | } | ||
168 | EXPORT_SYMBOL_GPL(sysfs_create_groups); | ||
132 | 169 | ||
133 | /** | 170 | /** |
134 | * sysfs_update_group - given a directory kobject, update an attribute group | 171 | * sysfs_update_group - given a directory kobject, update an attribute group |
@@ -152,11 +189,18 @@ int sysfs_update_group(struct kobject *kobj, | |||
152 | { | 189 | { |
153 | return internal_create_group(kobj, 1, grp); | 190 | return internal_create_group(kobj, 1, grp); |
154 | } | 191 | } |
192 | EXPORT_SYMBOL_GPL(sysfs_update_group); | ||
155 | 193 | ||
156 | 194 | /** | |
157 | 195 | * sysfs_remove_group: remove a group from a kobject | |
158 | void sysfs_remove_group(struct kobject * kobj, | 196 | * @kobj: kobject to remove the group from |
159 | const struct attribute_group * grp) | 197 | * @grp: group to remove |
198 | * | ||
199 | * This function removes a group of attributes from a kobject. The attributes | ||
200 | * previously have to have been created for this group, otherwise it will fail. | ||
201 | */ | ||
202 | void sysfs_remove_group(struct kobject *kobj, | ||
203 | const struct attribute_group *grp) | ||
160 | { | 204 | { |
161 | struct sysfs_dirent *dir_sd = kobj->sd; | 205 | struct sysfs_dirent *dir_sd = kobj->sd; |
162 | struct sysfs_dirent *sd; | 206 | struct sysfs_dirent *sd; |
@@ -164,8 +208,9 @@ void sysfs_remove_group(struct kobject * kobj, | |||
164 | if (grp->name) { | 208 | if (grp->name) { |
165 | sd = sysfs_get_dirent(dir_sd, NULL, grp->name); | 209 | sd = sysfs_get_dirent(dir_sd, NULL, grp->name); |
166 | if (!sd) { | 210 | if (!sd) { |
167 | WARN(!sd, KERN_WARNING "sysfs group %p not found for " | 211 | WARN(!sd, KERN_WARNING |
168 | "kobject '%s'\n", grp, kobject_name(kobj)); | 212 | "sysfs group %p not found for kobject '%s'\n", |
213 | grp, kobject_name(kobj)); | ||
169 | return; | 214 | return; |
170 | } | 215 | } |
171 | } else | 216 | } else |
@@ -177,6 +222,27 @@ void sysfs_remove_group(struct kobject * kobj, | |||
177 | 222 | ||
178 | sysfs_put(sd); | 223 | sysfs_put(sd); |
179 | } | 224 | } |
225 | EXPORT_SYMBOL_GPL(sysfs_remove_group); | ||
226 | |||
227 | /** | ||
228 | * sysfs_remove_groups - remove a list of groups | ||
229 | * | ||
230 | * @kobj: The kobject for the groups to be removed from | ||
231 | * @groups: NULL terminated list of groups to be removed | ||
232 | * | ||
233 | * If groups is not NULL, remove the specified groups from the kobject. | ||
234 | */ | ||
235 | void sysfs_remove_groups(struct kobject *kobj, | ||
236 | const struct attribute_group **groups) | ||
237 | { | ||
238 | int i; | ||
239 | |||
240 | if (!groups) | ||
241 | return; | ||
242 | for (i = 0; groups[i]; i++) | ||
243 | sysfs_remove_group(kobj, groups[i]); | ||
244 | } | ||
245 | EXPORT_SYMBOL_GPL(sysfs_remove_groups); | ||
180 | 246 | ||
181 | /** | 247 | /** |
182 | * sysfs_merge_group - merge files into a pre-existing attribute group. | 248 | * 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, | |||
273 | } | 339 | } |
274 | } | 340 | } |
275 | EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); | 341 | EXPORT_SYMBOL_GPL(sysfs_remove_link_from_group); |
276 | |||
277 | EXPORT_SYMBOL_GPL(sysfs_create_group); | ||
278 | EXPORT_SYMBOL_GPL(sysfs_update_group); | ||
279 | EXPORT_SYMBOL_GPL(sysfs_remove_group); | ||
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c index 3e2837a633ed..963f910c8034 100644 --- a/fs/sysfs/inode.c +++ b/fs/sysfs/inode.c | |||
@@ -10,7 +10,7 @@ | |||
10 | * Please see Documentation/filesystems/sysfs.txt for more information. | 10 | * Please see Documentation/filesystems/sysfs.txt for more information. |
11 | */ | 11 | */ |
12 | 12 | ||
13 | #undef DEBUG | 13 | #undef DEBUG |
14 | 14 | ||
15 | #include <linux/pagemap.h> | 15 | #include <linux/pagemap.h> |
16 | #include <linux/namei.h> | 16 | #include <linux/namei.h> |
@@ -36,7 +36,7 @@ static struct backing_dev_info sysfs_backing_dev_info = { | |||
36 | .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, | 36 | .capabilities = BDI_CAP_NO_ACCT_AND_WRITEBACK, |
37 | }; | 37 | }; |
38 | 38 | ||
39 | static const struct inode_operations sysfs_inode_operations ={ | 39 | static const struct inode_operations sysfs_inode_operations = { |
40 | .permission = sysfs_permission, | 40 | .permission = sysfs_permission, |
41 | .setattr = sysfs_setattr, | 41 | .setattr = sysfs_setattr, |
42 | .getattr = sysfs_getattr, | 42 | .getattr = sysfs_getattr, |
@@ -67,7 +67,7 @@ static struct sysfs_inode_attrs *sysfs_init_inode_attrs(struct sysfs_dirent *sd) | |||
67 | return attrs; | 67 | return attrs; |
68 | } | 68 | } |
69 | 69 | ||
70 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr * iattr) | 70 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr) |
71 | { | 71 | { |
72 | struct sysfs_inode_attrs *sd_attrs; | 72 | struct sysfs_inode_attrs *sd_attrs; |
73 | struct iattr *iattrs; | 73 | struct iattr *iattrs; |
@@ -128,7 +128,8 @@ out: | |||
128 | return error; | 128 | return error; |
129 | } | 129 | } |
130 | 130 | ||
131 | static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, u32 *secdata_len) | 131 | static int sysfs_sd_setsecdata(struct sysfs_dirent *sd, void **secdata, |
132 | u32 *secdata_len) | ||
132 | { | 133 | { |
133 | struct sysfs_inode_attrs *iattrs; | 134 | struct sysfs_inode_attrs *iattrs; |
134 | void *old_secdata; | 135 | void *old_secdata; |
@@ -186,13 +187,13 @@ out: | |||
186 | return error; | 187 | return error; |
187 | } | 188 | } |
188 | 189 | ||
189 | static inline void set_default_inode_attr(struct inode * inode, umode_t mode) | 190 | static inline void set_default_inode_attr(struct inode *inode, umode_t mode) |
190 | { | 191 | { |
191 | inode->i_mode = mode; | 192 | inode->i_mode = mode; |
192 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; | 193 | inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME; |
193 | } | 194 | } |
194 | 195 | ||
195 | static inline void set_inode_attr(struct inode * inode, struct iattr * iattr) | 196 | static inline void set_inode_attr(struct inode *inode, struct iattr *iattr) |
196 | { | 197 | { |
197 | inode->i_uid = iattr->ia_uid; | 198 | inode->i_uid = iattr->ia_uid; |
198 | inode->i_gid = iattr->ia_gid; | 199 | inode->i_gid = iattr->ia_gid; |
@@ -220,7 +221,8 @@ static void sysfs_refresh_inode(struct sysfs_dirent *sd, struct inode *inode) | |||
220 | set_nlink(inode, sd->s_dir.subdirs + 2); | 221 | set_nlink(inode, sd->s_dir.subdirs + 2); |
221 | } | 222 | } |
222 | 223 | ||
223 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat) | 224 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
225 | struct kstat *stat) | ||
224 | { | 226 | { |
225 | struct sysfs_dirent *sd = dentry->d_fsdata; | 227 | struct sysfs_dirent *sd = dentry->d_fsdata; |
226 | struct inode *inode = dentry->d_inode; | 228 | struct inode *inode = dentry->d_inode; |
@@ -285,7 +287,7 @@ static void sysfs_init_inode(struct sysfs_dirent *sd, struct inode *inode) | |||
285 | * RETURNS: | 287 | * RETURNS: |
286 | * Pointer to allocated inode on success, NULL on failure. | 288 | * Pointer to allocated inode on success, NULL on failure. |
287 | */ | 289 | */ |
288 | struct inode * sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd) | 290 | struct inode *sysfs_get_inode(struct super_block *sb, struct sysfs_dirent *sd) |
289 | { | 291 | { |
290 | struct inode *inode; | 292 | struct inode *inode; |
291 | 293 | ||
@@ -312,7 +314,8 @@ void sysfs_evict_inode(struct inode *inode) | |||
312 | sysfs_put(sd); | 314 | sysfs_put(sd); |
313 | } | 315 | } |
314 | 316 | ||
315 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name) | 317 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, |
318 | const char *name) | ||
316 | { | 319 | { |
317 | struct sysfs_addrm_cxt acxt; | 320 | struct sysfs_addrm_cxt acxt; |
318 | struct sysfs_dirent *sd; | 321 | struct sysfs_dirent *sd; |
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c index afd83273e6ce..fd7ce7a39f91 100644 --- a/fs/sysfs/mount.c +++ b/fs/sysfs/mount.c | |||
@@ -64,7 +64,7 @@ static int sysfs_fill_super(struct super_block *sb, void *data, int silent) | |||
64 | /* instantiate and link root dentry */ | 64 | /* instantiate and link root dentry */ |
65 | root = d_make_root(inode); | 65 | root = d_make_root(inode); |
66 | if (!root) { | 66 | if (!root) { |
67 | pr_debug("%s: could not get root dentry!\n",__func__); | 67 | pr_debug("%s: could not get root dentry!\n", __func__); |
68 | return -ENOMEM; | 68 | return -ENOMEM; |
69 | } | 69 | } |
70 | root->d_fsdata = &sysfs_root; | 70 | root->d_fsdata = &sysfs_root; |
diff --git a/fs/sysfs/symlink.c b/fs/sysfs/symlink.c index 8c940df97a52..2dd4507d9edd 100644 --- a/fs/sysfs/symlink.c +++ b/fs/sysfs/symlink.c | |||
@@ -125,6 +125,7 @@ int sysfs_create_link(struct kobject *kobj, struct kobject *target, | |||
125 | { | 125 | { |
126 | return sysfs_do_create_link(kobj, target, name, 1); | 126 | return sysfs_do_create_link(kobj, target, name, 1); |
127 | } | 127 | } |
128 | EXPORT_SYMBOL_GPL(sysfs_create_link); | ||
128 | 129 | ||
129 | /** | 130 | /** |
130 | * sysfs_create_link_nowarn - create symlink between two objects. | 131 | * sysfs_create_link_nowarn - create symlink between two objects. |
@@ -166,8 +167,7 @@ void sysfs_delete_link(struct kobject *kobj, struct kobject *targ, | |||
166 | * @kobj: object we're acting for. | 167 | * @kobj: object we're acting for. |
167 | * @name: name of the symlink to remove. | 168 | * @name: name of the symlink to remove. |
168 | */ | 169 | */ |
169 | 170 | void sysfs_remove_link(struct kobject *kobj, const char *name) | |
170 | void sysfs_remove_link(struct kobject * kobj, const char * name) | ||
171 | { | 171 | { |
172 | struct sysfs_dirent *parent_sd = NULL; | 172 | struct sysfs_dirent *parent_sd = NULL; |
173 | 173 | ||
@@ -178,6 +178,7 @@ void sysfs_remove_link(struct kobject * kobj, const char * name) | |||
178 | 178 | ||
179 | sysfs_hash_and_remove(parent_sd, NULL, name); | 179 | sysfs_hash_and_remove(parent_sd, NULL, name); |
180 | } | 180 | } |
181 | EXPORT_SYMBOL_GPL(sysfs_remove_link); | ||
181 | 182 | ||
182 | /** | 183 | /** |
183 | * sysfs_rename_link - rename symlink in object's directory. | 184 | * sysfs_rename_link - rename symlink in object's directory. |
@@ -223,6 +224,7 @@ out: | |||
223 | sysfs_put(sd); | 224 | sysfs_put(sd); |
224 | return result; | 225 | return result; |
225 | } | 226 | } |
227 | EXPORT_SYMBOL_GPL(sysfs_rename_link); | ||
226 | 228 | ||
227 | static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, | 229 | static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, |
228 | struct sysfs_dirent *target_sd, char *path) | 230 | struct sysfs_dirent *target_sd, char *path) |
@@ -276,7 +278,7 @@ static int sysfs_get_target_path(struct sysfs_dirent *parent_sd, | |||
276 | return 0; | 278 | return 0; |
277 | } | 279 | } |
278 | 280 | ||
279 | static int sysfs_getlink(struct dentry *dentry, char * path) | 281 | static int sysfs_getlink(struct dentry *dentry, char *path) |
280 | { | 282 | { |
281 | struct sysfs_dirent *sd = dentry->d_fsdata; | 283 | struct sysfs_dirent *sd = dentry->d_fsdata; |
282 | struct sysfs_dirent *parent_sd = sd->s_parent; | 284 | struct sysfs_dirent *parent_sd = sd->s_parent; |
@@ -295,7 +297,7 @@ static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
295 | int error = -ENOMEM; | 297 | int error = -ENOMEM; |
296 | unsigned long page = get_zeroed_page(GFP_KERNEL); | 298 | unsigned long page = get_zeroed_page(GFP_KERNEL); |
297 | if (page) { | 299 | if (page) { |
298 | error = sysfs_getlink(dentry, (char *) page); | 300 | error = sysfs_getlink(dentry, (char *) page); |
299 | if (error < 0) | 301 | if (error < 0) |
300 | free_page((unsigned long)page); | 302 | free_page((unsigned long)page); |
301 | } | 303 | } |
@@ -303,7 +305,8 @@ static void *sysfs_follow_link(struct dentry *dentry, struct nameidata *nd) | |||
303 | return NULL; | 305 | return NULL; |
304 | } | 306 | } |
305 | 307 | ||
306 | static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, void *cookie) | 308 | static void sysfs_put_link(struct dentry *dentry, struct nameidata *nd, |
309 | void *cookie) | ||
307 | { | 310 | { |
308 | char *page = nd_get_link(nd); | 311 | char *page = nd_get_link(nd); |
309 | if (!IS_ERR(page)) | 312 | if (!IS_ERR(page)) |
@@ -319,8 +322,3 @@ const struct inode_operations sysfs_symlink_inode_operations = { | |||
319 | .getattr = sysfs_getattr, | 322 | .getattr = sysfs_getattr, |
320 | .permission = sysfs_permission, | 323 | .permission = sysfs_permission, |
321 | }; | 324 | }; |
322 | |||
323 | |||
324 | EXPORT_SYMBOL_GPL(sysfs_create_link); | ||
325 | EXPORT_SYMBOL_GPL(sysfs_remove_link); | ||
326 | EXPORT_SYMBOL_GPL(sysfs_rename_link); | ||
diff --git a/fs/sysfs/sysfs.h b/fs/sysfs/sysfs.h index d1e4043eb0c3..b6deca3e301d 100644 --- a/fs/sysfs/sysfs.h +++ b/fs/sysfs/sysfs.h | |||
@@ -78,7 +78,7 @@ struct sysfs_dirent { | |||
78 | }; | 78 | }; |
79 | 79 | ||
80 | unsigned short s_flags; | 80 | unsigned short s_flags; |
81 | umode_t s_mode; | 81 | umode_t s_mode; |
82 | unsigned int s_ino; | 82 | unsigned int s_ino; |
83 | struct sysfs_inode_attrs *s_iattr; | 83 | struct sysfs_inode_attrs *s_iattr; |
84 | }; | 84 | }; |
@@ -123,9 +123,9 @@ do { \ | |||
123 | key = &attr->skey; \ | 123 | key = &attr->skey; \ |
124 | \ | 124 | \ |
125 | lockdep_init_map(&sd->dep_map, "s_active", key, 0); \ | 125 | lockdep_init_map(&sd->dep_map, "s_active", key, 0); \ |
126 | } while(0) | 126 | } while (0) |
127 | #else | 127 | #else |
128 | #define sysfs_dirent_init_lockdep(sd) do {} while(0) | 128 | #define sysfs_dirent_init_lockdep(sd) do {} while (0) |
129 | #endif | 129 | #endif |
130 | 130 | ||
131 | /* | 131 | /* |
@@ -186,8 +186,8 @@ int sysfs_create_subdir(struct kobject *kobj, const char *name, | |||
186 | struct sysfs_dirent **p_sd); | 186 | struct sysfs_dirent **p_sd); |
187 | void sysfs_remove_subdir(struct sysfs_dirent *sd); | 187 | void sysfs_remove_subdir(struct sysfs_dirent *sd); |
188 | 188 | ||
189 | int sysfs_rename(struct sysfs_dirent *sd, | 189 | int sysfs_rename(struct sysfs_dirent *sd, struct sysfs_dirent *new_parent_sd, |
190 | struct sysfs_dirent *new_parent_sd, const void *ns, const char *new_name); | 190 | const void *ns, const char *new_name); |
191 | 191 | ||
192 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) | 192 | static inline struct sysfs_dirent *__sysfs_get(struct sysfs_dirent *sd) |
193 | { | 193 | { |
@@ -214,10 +214,12 @@ void sysfs_evict_inode(struct inode *inode); | |||
214 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); | 214 | int sysfs_sd_setattr(struct sysfs_dirent *sd, struct iattr *iattr); |
215 | int sysfs_permission(struct inode *inode, int mask); | 215 | int sysfs_permission(struct inode *inode, int mask); |
216 | int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); | 216 | int sysfs_setattr(struct dentry *dentry, struct iattr *iattr); |
217 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat); | 217 | int sysfs_getattr(struct vfsmount *mnt, struct dentry *dentry, |
218 | struct kstat *stat); | ||
218 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, | 219 | int sysfs_setxattr(struct dentry *dentry, const char *name, const void *value, |
219 | size_t size, int flags); | 220 | size_t size, int flags); |
220 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, const char *name); | 221 | int sysfs_hash_and_remove(struct sysfs_dirent *dir_sd, const void *ns, |
222 | const char *name); | ||
221 | int sysfs_inode_init(void); | 223 | int sysfs_inode_init(void); |
222 | 224 | ||
223 | /* | 225 | /* |
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h index d68b4ea7343c..263489d0788d 100644 --- a/include/linux/debugfs.h +++ b/include/linux/debugfs.h | |||
@@ -192,6 +192,13 @@ static inline struct dentry *debugfs_create_x32(const char *name, umode_t mode, | |||
192 | return ERR_PTR(-ENODEV); | 192 | return ERR_PTR(-ENODEV); |
193 | } | 193 | } |
194 | 194 | ||
195 | static inline struct dentry *debugfs_create_x64(const char *name, umode_t mode, | ||
196 | struct dentry *parent, | ||
197 | u64 *value) | ||
198 | { | ||
199 | return ERR_PTR(-ENODEV); | ||
200 | } | ||
201 | |||
195 | static inline struct dentry *debugfs_create_size_t(const char *name, umode_t mode, | 202 | static inline struct dentry *debugfs_create_size_t(const char *name, umode_t mode, |
196 | struct dentry *parent, | 203 | struct dentry *parent, |
197 | size_t *value) | 204 | size_t *value) |
diff --git a/include/linux/device.h b/include/linux/device.h index 7d960d581e9c..389becc88be6 100644 --- a/include/linux/device.h +++ b/include/linux/device.h | |||
@@ -66,6 +66,9 @@ extern void bus_remove_file(struct bus_type *, struct bus_attribute *); | |||
66 | * @bus_attrs: Default attributes of the bus. | 66 | * @bus_attrs: Default attributes of the bus. |
67 | * @dev_attrs: Default attributes of the devices on the bus. | 67 | * @dev_attrs: Default attributes of the devices on the bus. |
68 | * @drv_attrs: Default attributes of the device drivers on the bus. | 68 | * @drv_attrs: Default attributes of the device drivers on the bus. |
69 | * @bus_groups: Default attributes of the bus. | ||
70 | * @dev_groups: Default attributes of the devices on the bus. | ||
71 | * @drv_groups: Default attributes of the device drivers on the bus. | ||
69 | * @match: Called, perhaps multiple times, whenever a new device or driver | 72 | * @match: Called, perhaps multiple times, whenever a new device or driver |
70 | * is added for this bus. It should return a nonzero value if the | 73 | * is added for this bus. It should return a nonzero value if the |
71 | * given device can be handled by the given driver. | 74 | * given device can be handled by the given driver. |
@@ -103,9 +106,12 @@ struct bus_type { | |||
103 | const char *name; | 106 | const char *name; |
104 | const char *dev_name; | 107 | const char *dev_name; |
105 | struct device *dev_root; | 108 | struct device *dev_root; |
106 | struct bus_attribute *bus_attrs; | 109 | struct bus_attribute *bus_attrs; /* use bus_groups instead */ |
107 | struct device_attribute *dev_attrs; | 110 | struct device_attribute *dev_attrs; /* use dev_groups instead */ |
108 | struct driver_attribute *drv_attrs; | 111 | struct driver_attribute *drv_attrs; /* use drv_groups instead */ |
112 | const struct attribute_group **bus_groups; | ||
113 | const struct attribute_group **dev_groups; | ||
114 | const struct attribute_group **drv_groups; | ||
109 | 115 | ||
110 | int (*match)(struct device *dev, struct device_driver *drv); | 116 | int (*match)(struct device *dev, struct device_driver *drv); |
111 | int (*uevent)(struct device *dev, struct kobj_uevent_env *env); | 117 | int (*uevent)(struct device *dev, struct kobj_uevent_env *env); |
@@ -271,6 +277,8 @@ struct driver_attribute { | |||
271 | struct driver_attribute driver_attr_##_name = __ATTR_RW(_name) | 277 | struct driver_attribute driver_attr_##_name = __ATTR_RW(_name) |
272 | #define DRIVER_ATTR_RO(_name) \ | 278 | #define DRIVER_ATTR_RO(_name) \ |
273 | struct driver_attribute driver_attr_##_name = __ATTR_RO(_name) | 279 | struct driver_attribute driver_attr_##_name = __ATTR_RO(_name) |
280 | #define DRIVER_ATTR_WO(_name) \ | ||
281 | struct driver_attribute driver_attr_##_name = __ATTR_WO(_name) | ||
274 | 282 | ||
275 | extern int __must_check driver_create_file(struct device_driver *driver, | 283 | extern int __must_check driver_create_file(struct device_driver *driver, |
276 | const struct driver_attribute *attr); | 284 | const struct driver_attribute *attr); |
@@ -528,6 +536,8 @@ ssize_t device_store_bool(struct device *dev, struct device_attribute *attr, | |||
528 | struct device_attribute dev_attr_##_name = __ATTR_RW(_name) | 536 | struct device_attribute dev_attr_##_name = __ATTR_RW(_name) |
529 | #define DEVICE_ATTR_RO(_name) \ | 537 | #define DEVICE_ATTR_RO(_name) \ |
530 | struct device_attribute dev_attr_##_name = __ATTR_RO(_name) | 538 | struct device_attribute dev_attr_##_name = __ATTR_RO(_name) |
539 | #define DEVICE_ATTR_WO(_name) \ | ||
540 | struct device_attribute dev_attr_##_name = __ATTR_WO(_name) | ||
531 | #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ | 541 | #define DEVICE_ULONG_ATTR(_name, _mode, _var) \ |
532 | struct dev_ext_attribute dev_attr_##_name = \ | 542 | struct dev_ext_attribute dev_attr_##_name = \ |
533 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } | 543 | { __ATTR(_name, _mode, device_show_ulong, device_store_ulong), &(_var) } |
diff --git a/include/linux/kobject.h b/include/linux/kobject.h index 939b11268c86..de6dcbcc6ef7 100644 --- a/include/linux/kobject.h +++ b/include/linux/kobject.h | |||
@@ -26,6 +26,7 @@ | |||
26 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
27 | #include <linux/wait.h> | 27 | #include <linux/wait.h> |
28 | #include <linux/atomic.h> | 28 | #include <linux/atomic.h> |
29 | #include <linux/workqueue.h> | ||
29 | 30 | ||
30 | #define UEVENT_HELPER_PATH_LEN 256 | 31 | #define UEVENT_HELPER_PATH_LEN 256 |
31 | #define UEVENT_NUM_ENVP 32 /* number of env pointers */ | 32 | #define UEVENT_NUM_ENVP 32 /* number of env pointers */ |
@@ -65,6 +66,9 @@ struct kobject { | |||
65 | struct kobj_type *ktype; | 66 | struct kobj_type *ktype; |
66 | struct sysfs_dirent *sd; | 67 | struct sysfs_dirent *sd; |
67 | struct kref kref; | 68 | struct kref kref; |
69 | #ifdef CONFIG_DEBUG_KOBJECT_RELEASE | ||
70 | struct delayed_work release; | ||
71 | #endif | ||
68 | unsigned int state_initialized:1; | 72 | unsigned int state_initialized:1; |
69 | unsigned int state_in_sysfs:1; | 73 | unsigned int state_in_sysfs:1; |
70 | unsigned int state_add_uevent_sent:1; | 74 | unsigned int state_add_uevent_sent:1; |
diff --git a/include/linux/memory.h b/include/linux/memory.h index 85c31a8e2904..9a6bbf76452d 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h | |||
@@ -25,16 +25,9 @@ | |||
25 | struct memory_block { | 25 | struct memory_block { |
26 | unsigned long start_section_nr; | 26 | unsigned long start_section_nr; |
27 | unsigned long end_section_nr; | 27 | unsigned long end_section_nr; |
28 | unsigned long state; | 28 | unsigned long state; /* serialized by the dev->lock */ |
29 | int section_count; | 29 | int section_count; /* serialized by mem_sysfs_mutex */ |
30 | 30 | int online_type; /* for passing data to online routine */ | |
31 | /* | ||
32 | * This serializes all state change requests. It isn't | ||
33 | * held during creation because the control files are | ||
34 | * created long after the critical areas during | ||
35 | * initialization. | ||
36 | */ | ||
37 | struct mutex state_mutex; | ||
38 | int phys_device; /* to which fru does this belong? */ | 31 | int phys_device; /* to which fru does this belong? */ |
39 | void *hw; /* optional pointer to fw/hw data */ | 32 | void *hw; /* optional pointer to fw/hw data */ |
40 | int (*phys_callback)(struct memory_block *); | 33 | int (*phys_callback)(struct memory_block *); |
@@ -125,7 +118,6 @@ extern struct memory_block *find_memory_block_hinted(struct mem_section *, | |||
125 | struct memory_block *); | 118 | struct memory_block *); |
126 | extern struct memory_block *find_memory_block(struct mem_section *); | 119 | extern struct memory_block *find_memory_block(struct mem_section *); |
127 | #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) | 120 | #define CONFIG_MEM_BLOCK_SIZE (PAGES_PER_SECTION<<PAGE_SHIFT) |
128 | enum mem_add_context { BOOT, HOTPLUG }; | ||
129 | #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ | 121 | #endif /* CONFIG_MEMORY_HOTPLUG_SPARSE */ |
130 | 122 | ||
131 | #ifdef CONFIG_MEMORY_HOTPLUG | 123 | #ifdef CONFIG_MEMORY_HOTPLUG |
diff --git a/include/linux/pps_kernel.h b/include/linux/pps_kernel.h index 7db3eb93a079..1d2cd21242e8 100644 --- a/include/linux/pps_kernel.h +++ b/include/linux/pps_kernel.h | |||
@@ -80,7 +80,7 @@ struct pps_device { | |||
80 | * Global variables | 80 | * Global variables |
81 | */ | 81 | */ |
82 | 82 | ||
83 | extern struct device_attribute pps_attrs[]; | 83 | extern const struct attribute_group *pps_groups[]; |
84 | 84 | ||
85 | /* | 85 | /* |
86 | * Internal functions. | 86 | * Internal functions. |
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h index 9e8a9b555ad6..11baec7c9b26 100644 --- a/include/linux/sysfs.h +++ b/include/linux/sysfs.h | |||
@@ -51,9 +51,9 @@ do { \ | |||
51 | static struct lock_class_key __key; \ | 51 | static struct lock_class_key __key; \ |
52 | \ | 52 | \ |
53 | (attr)->key = &__key; \ | 53 | (attr)->key = &__key; \ |
54 | } while(0) | 54 | } while (0) |
55 | #else | 55 | #else |
56 | #define sysfs_attr_init(attr) do {} while(0) | 56 | #define sysfs_attr_init(attr) do {} while (0) |
57 | #endif | 57 | #endif |
58 | 58 | ||
59 | struct attribute_group { | 59 | struct attribute_group { |
@@ -69,7 +69,7 @@ struct attribute_group { | |||
69 | * for examples.. | 69 | * for examples.. |
70 | */ | 70 | */ |
71 | 71 | ||
72 | #define __ATTR(_name,_mode,_show,_store) { \ | 72 | #define __ATTR(_name, _mode, _show, _store) { \ |
73 | .attr = {.name = __stringify(_name), .mode = _mode }, \ | 73 | .attr = {.name = __stringify(_name), .mode = _mode }, \ |
74 | .show = _show, \ | 74 | .show = _show, \ |
75 | .store = _store, \ | 75 | .store = _store, \ |
@@ -80,6 +80,11 @@ struct attribute_group { | |||
80 | .show = _name##_show, \ | 80 | .show = _name##_show, \ |
81 | } | 81 | } |
82 | 82 | ||
83 | #define __ATTR_WO(_name) { \ | ||
84 | .attr = { .name = __stringify(_name), .mode = S_IWUSR }, \ | ||
85 | .store = _name##_store, \ | ||
86 | } | ||
87 | |||
83 | #define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \ | 88 | #define __ATTR_RW(_name) __ATTR(_name, (S_IWUSR | S_IRUGO), \ |
84 | _name##_show, _name##_store) | 89 | _name##_show, _name##_store) |
85 | 90 | ||
@@ -108,8 +113,6 @@ static const struct attribute_group _name##_group = { \ | |||
108 | }; \ | 113 | }; \ |
109 | __ATTRIBUTE_GROUPS(_name) | 114 | __ATTRIBUTE_GROUPS(_name) |
110 | 115 | ||
111 | #define attr_name(_attr) (_attr).attr.name | ||
112 | |||
113 | struct file; | 116 | struct file; |
114 | struct vm_area_struct; | 117 | struct vm_area_struct; |
115 | 118 | ||
@@ -119,7 +122,7 @@ struct bin_attribute { | |||
119 | void *private; | 122 | void *private; |
120 | ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, | 123 | ssize_t (*read)(struct file *, struct kobject *, struct bin_attribute *, |
121 | char *, loff_t, size_t); | 124 | char *, loff_t, size_t); |
122 | ssize_t (*write)(struct file *,struct kobject *, struct bin_attribute *, | 125 | ssize_t (*write)(struct file *, struct kobject *, struct bin_attribute *, |
123 | char *, loff_t, size_t); | 126 | char *, loff_t, size_t); |
124 | int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, | 127 | int (*mmap)(struct file *, struct kobject *, struct bin_attribute *attr, |
125 | struct vm_area_struct *vma); | 128 | struct vm_area_struct *vma); |
@@ -153,7 +156,7 @@ struct bin_attribute { | |||
153 | 156 | ||
154 | #define __BIN_ATTR_RW(_name, _size) __BIN_ATTR(_name, \ | 157 | #define __BIN_ATTR_RW(_name, _size) __BIN_ATTR(_name, \ |
155 | (S_IWUSR | S_IRUGO), _name##_read, \ | 158 | (S_IWUSR | S_IRUGO), _name##_read, \ |
156 | _name##_write) | 159 | _name##_write, _size) |
157 | 160 | ||
158 | #define __BIN_ATTR_NULL __ATTR_NULL | 161 | #define __BIN_ATTR_NULL __ATTR_NULL |
159 | 162 | ||
@@ -168,8 +171,8 @@ struct bin_attribute bin_attr_##_name = __BIN_ATTR_RO(_name, _size) | |||
168 | struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size) | 171 | struct bin_attribute bin_attr_##_name = __BIN_ATTR_RW(_name, _size) |
169 | 172 | ||
170 | struct sysfs_ops { | 173 | struct sysfs_ops { |
171 | ssize_t (*show)(struct kobject *, struct attribute *,char *); | 174 | ssize_t (*show)(struct kobject *, struct attribute *, char *); |
172 | ssize_t (*store)(struct kobject *,struct attribute *,const char *, size_t); | 175 | ssize_t (*store)(struct kobject *, struct attribute *, const char *, size_t); |
173 | const void *(*namespace)(struct kobject *, const struct attribute *); | 176 | const void *(*namespace)(struct kobject *, const struct attribute *); |
174 | }; | 177 | }; |
175 | 178 | ||
@@ -215,10 +218,14 @@ void sysfs_delete_link(struct kobject *dir, struct kobject *targ, | |||
215 | 218 | ||
216 | int __must_check sysfs_create_group(struct kobject *kobj, | 219 | int __must_check sysfs_create_group(struct kobject *kobj, |
217 | const struct attribute_group *grp); | 220 | const struct attribute_group *grp); |
221 | int __must_check sysfs_create_groups(struct kobject *kobj, | ||
222 | const struct attribute_group **groups); | ||
218 | int sysfs_update_group(struct kobject *kobj, | 223 | int sysfs_update_group(struct kobject *kobj, |
219 | const struct attribute_group *grp); | 224 | const struct attribute_group *grp); |
220 | void sysfs_remove_group(struct kobject *kobj, | 225 | void sysfs_remove_group(struct kobject *kobj, |
221 | const struct attribute_group *grp); | 226 | const struct attribute_group *grp); |
227 | void sysfs_remove_groups(struct kobject *kobj, | ||
228 | const struct attribute_group **groups); | ||
222 | int sysfs_add_file_to_group(struct kobject *kobj, | 229 | int sysfs_add_file_to_group(struct kobject *kobj, |
223 | const struct attribute *attr, const char *group); | 230 | const struct attribute *attr, const char *group); |
224 | void sysfs_remove_file_from_group(struct kobject *kobj, | 231 | void sysfs_remove_file_from_group(struct kobject *kobj, |
@@ -343,6 +350,12 @@ static inline int sysfs_create_group(struct kobject *kobj, | |||
343 | return 0; | 350 | return 0; |
344 | } | 351 | } |
345 | 352 | ||
353 | static inline int sysfs_create_groups(struct kobject *kobj, | ||
354 | const struct attribute_group **groups) | ||
355 | { | ||
356 | return 0; | ||
357 | } | ||
358 | |||
346 | static inline int sysfs_update_group(struct kobject *kobj, | 359 | static inline int sysfs_update_group(struct kobject *kobj, |
347 | const struct attribute_group *grp) | 360 | const struct attribute_group *grp) |
348 | { | 361 | { |
@@ -354,6 +367,11 @@ static inline void sysfs_remove_group(struct kobject *kobj, | |||
354 | { | 367 | { |
355 | } | 368 | } |
356 | 369 | ||
370 | static inline void sysfs_remove_groups(struct kobject *kobj, | ||
371 | const struct attribute_group **groups) | ||
372 | { | ||
373 | } | ||
374 | |||
357 | static inline int sysfs_add_file_to_group(struct kobject *kobj, | 375 | static inline int sysfs_add_file_to_group(struct kobject *kobj, |
358 | const struct attribute *attr, const char *group) | 376 | const struct attribute *attr, const char *group) |
359 | { | 377 | { |
diff --git a/kernel/workqueue.c b/kernel/workqueue.c index e93f7b9067d8..5f8ee91abdff 100644 --- a/kernel/workqueue.c +++ b/kernel/workqueue.c | |||
@@ -3095,25 +3095,26 @@ static struct workqueue_struct *dev_to_wq(struct device *dev) | |||
3095 | return wq_dev->wq; | 3095 | return wq_dev->wq; |
3096 | } | 3096 | } |
3097 | 3097 | ||
3098 | static ssize_t wq_per_cpu_show(struct device *dev, | 3098 | static ssize_t per_cpu_show(struct device *dev, struct device_attribute *attr, |
3099 | struct device_attribute *attr, char *buf) | 3099 | char *buf) |
3100 | { | 3100 | { |
3101 | struct workqueue_struct *wq = dev_to_wq(dev); | 3101 | struct workqueue_struct *wq = dev_to_wq(dev); |
3102 | 3102 | ||
3103 | return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)!(wq->flags & WQ_UNBOUND)); | 3103 | return scnprintf(buf, PAGE_SIZE, "%d\n", (bool)!(wq->flags & WQ_UNBOUND)); |
3104 | } | 3104 | } |
3105 | static DEVICE_ATTR_RO(per_cpu); | ||
3105 | 3106 | ||
3106 | static ssize_t wq_max_active_show(struct device *dev, | 3107 | static ssize_t max_active_show(struct device *dev, |
3107 | struct device_attribute *attr, char *buf) | 3108 | struct device_attribute *attr, char *buf) |
3108 | { | 3109 | { |
3109 | struct workqueue_struct *wq = dev_to_wq(dev); | 3110 | struct workqueue_struct *wq = dev_to_wq(dev); |
3110 | 3111 | ||
3111 | return scnprintf(buf, PAGE_SIZE, "%d\n", wq->saved_max_active); | 3112 | return scnprintf(buf, PAGE_SIZE, "%d\n", wq->saved_max_active); |
3112 | } | 3113 | } |
3113 | 3114 | ||
3114 | static ssize_t wq_max_active_store(struct device *dev, | 3115 | static ssize_t max_active_store(struct device *dev, |
3115 | struct device_attribute *attr, | 3116 | struct device_attribute *attr, const char *buf, |
3116 | const char *buf, size_t count) | 3117 | size_t count) |
3117 | { | 3118 | { |
3118 | struct workqueue_struct *wq = dev_to_wq(dev); | 3119 | struct workqueue_struct *wq = dev_to_wq(dev); |
3119 | int val; | 3120 | int val; |
@@ -3124,12 +3125,14 @@ static ssize_t wq_max_active_store(struct device *dev, | |||
3124 | workqueue_set_max_active(wq, val); | 3125 | workqueue_set_max_active(wq, val); |
3125 | return count; | 3126 | return count; |
3126 | } | 3127 | } |
3128 | static DEVICE_ATTR_RW(max_active); | ||
3127 | 3129 | ||
3128 | static struct device_attribute wq_sysfs_attrs[] = { | 3130 | static struct attribute *wq_sysfs_attrs[] = { |
3129 | __ATTR(per_cpu, 0444, wq_per_cpu_show, NULL), | 3131 | &dev_attr_per_cpu.attr, |
3130 | __ATTR(max_active, 0644, wq_max_active_show, wq_max_active_store), | 3132 | &dev_attr_max_active.attr, |
3131 | __ATTR_NULL, | 3133 | NULL, |
3132 | }; | 3134 | }; |
3135 | ATTRIBUTE_GROUPS(wq_sysfs); | ||
3133 | 3136 | ||
3134 | static ssize_t wq_pool_ids_show(struct device *dev, | 3137 | static ssize_t wq_pool_ids_show(struct device *dev, |
3135 | struct device_attribute *attr, char *buf) | 3138 | struct device_attribute *attr, char *buf) |
@@ -3279,7 +3282,7 @@ static struct device_attribute wq_sysfs_unbound_attrs[] = { | |||
3279 | 3282 | ||
3280 | static struct bus_type wq_subsys = { | 3283 | static struct bus_type wq_subsys = { |
3281 | .name = "workqueue", | 3284 | .name = "workqueue", |
3282 | .dev_attrs = wq_sysfs_attrs, | 3285 | .dev_groups = wq_sysfs_groups, |
3283 | }; | 3286 | }; |
3284 | 3287 | ||
3285 | static int __init wq_sysfs_init(void) | 3288 | static int __init wq_sysfs_init(void) |
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug index 1501aa553221..444e1c12fea9 100644 --- a/lib/Kconfig.debug +++ b/lib/Kconfig.debug | |||
@@ -981,6 +981,25 @@ config DEBUG_KOBJECT | |||
981 | If you say Y here, some extra kobject debugging messages will be sent | 981 | If you say Y here, some extra kobject debugging messages will be sent |
982 | to the syslog. | 982 | to the syslog. |
983 | 983 | ||
984 | config DEBUG_KOBJECT_RELEASE | ||
985 | bool "kobject release debugging" | ||
986 | depends on DEBUG_KERNEL | ||
987 | help | ||
988 | kobjects are reference counted objects. This means that their | ||
989 | last reference count put is not predictable, and the kobject can | ||
990 | live on past the point at which a driver decides to drop it's | ||
991 | initial reference to the kobject gained on allocation. An | ||
992 | example of this would be a struct device which has just been | ||
993 | unregistered. | ||
994 | |||
995 | However, some buggy drivers assume that after such an operation, | ||
996 | the memory backing the kobject can be immediately freed. This | ||
997 | goes completely against the principles of a refcounted object. | ||
998 | |||
999 | If you say Y here, the kernel will delay the release of kobjects | ||
1000 | on the last reference count to improve the visibility of this | ||
1001 | kind of kobject release bug. | ||
1002 | |||
984 | config HAVE_DEBUG_BUGVERBOSE | 1003 | config HAVE_DEBUG_BUGVERBOSE |
985 | bool | 1004 | bool |
986 | 1005 | ||
diff --git a/lib/dynamic_debug.c b/lib/dynamic_debug.c index 99fec3ae405a..c37aeacd7651 100644 --- a/lib/dynamic_debug.c +++ b/lib/dynamic_debug.c | |||
@@ -309,7 +309,7 @@ static int ddebug_parse_query(char *words[], int nwords, | |||
309 | struct ddebug_query *query, const char *modname) | 309 | struct ddebug_query *query, const char *modname) |
310 | { | 310 | { |
311 | unsigned int i; | 311 | unsigned int i; |
312 | int rc; | 312 | int rc = 0; |
313 | 313 | ||
314 | /* check we have an even number of words */ | 314 | /* check we have an even number of words */ |
315 | if (nwords % 2 != 0) { | 315 | if (nwords % 2 != 0) { |
diff --git a/lib/kobject.c b/lib/kobject.c index 4a1f33d43548..1d46c151a4ae 100644 --- a/lib/kobject.c +++ b/lib/kobject.c | |||
@@ -545,8 +545,8 @@ static void kobject_cleanup(struct kobject *kobj) | |||
545 | struct kobj_type *t = get_ktype(kobj); | 545 | struct kobj_type *t = get_ktype(kobj); |
546 | const char *name = kobj->name; | 546 | const char *name = kobj->name; |
547 | 547 | ||
548 | pr_debug("kobject: '%s' (%p): %s\n", | 548 | pr_debug("kobject: '%s' (%p): %s, parent %p\n", |
549 | kobject_name(kobj), kobj, __func__); | 549 | kobject_name(kobj), kobj, __func__, kobj->parent); |
550 | 550 | ||
551 | if (t && !t->release) | 551 | if (t && !t->release) |
552 | pr_debug("kobject: '%s' (%p): does not have a release() " | 552 | pr_debug("kobject: '%s' (%p): does not have a release() " |
@@ -580,9 +580,25 @@ static void kobject_cleanup(struct kobject *kobj) | |||
580 | } | 580 | } |
581 | } | 581 | } |
582 | 582 | ||
583 | #ifdef CONFIG_DEBUG_KOBJECT_RELEASE | ||
584 | static void kobject_delayed_cleanup(struct work_struct *work) | ||
585 | { | ||
586 | kobject_cleanup(container_of(to_delayed_work(work), | ||
587 | struct kobject, release)); | ||
588 | } | ||
589 | #endif | ||
590 | |||
583 | static void kobject_release(struct kref *kref) | 591 | static void kobject_release(struct kref *kref) |
584 | { | 592 | { |
585 | kobject_cleanup(container_of(kref, struct kobject, kref)); | 593 | struct kobject *kobj = container_of(kref, struct kobject, kref); |
594 | #ifdef CONFIG_DEBUG_KOBJECT_RELEASE | ||
595 | pr_debug("kobject: '%s' (%p): %s, parent %p (delayed)\n", | ||
596 | kobject_name(kobj), kobj, __func__, kobj->parent); | ||
597 | INIT_DELAYED_WORK(&kobj->release, kobject_delayed_cleanup); | ||
598 | schedule_delayed_work(&kobj->release, HZ); | ||
599 | #else | ||
600 | kobject_cleanup(kobj); | ||
601 | #endif | ||
586 | } | 602 | } |
587 | 603 | ||
588 | /** | 604 | /** |
diff --git a/mm/backing-dev.c b/mm/backing-dev.c index e04454cdb33f..37d9edcd14cf 100644 --- a/mm/backing-dev.c +++ b/mm/backing-dev.c | |||
@@ -180,7 +180,8 @@ static ssize_t name##_show(struct device *dev, \ | |||
180 | struct backing_dev_info *bdi = dev_get_drvdata(dev); \ | 180 | struct backing_dev_info *bdi = dev_get_drvdata(dev); \ |
181 | \ | 181 | \ |
182 | return snprintf(page, PAGE_SIZE-1, "%lld\n", (long long)expr); \ | 182 | return snprintf(page, PAGE_SIZE-1, "%lld\n", (long long)expr); \ |
183 | } | 183 | } \ |
184 | static DEVICE_ATTR_RW(name); | ||
184 | 185 | ||
185 | BDI_SHOW(read_ahead_kb, K(bdi->ra_pages)) | 186 | BDI_SHOW(read_ahead_kb, K(bdi->ra_pages)) |
186 | 187 | ||
@@ -231,14 +232,16 @@ static ssize_t stable_pages_required_show(struct device *dev, | |||
231 | return snprintf(page, PAGE_SIZE-1, "%d\n", | 232 | return snprintf(page, PAGE_SIZE-1, "%d\n", |
232 | bdi_cap_stable_pages_required(bdi) ? 1 : 0); | 233 | bdi_cap_stable_pages_required(bdi) ? 1 : 0); |
233 | } | 234 | } |
235 | static DEVICE_ATTR_RO(stable_pages_required); | ||
234 | 236 | ||
235 | static struct device_attribute bdi_dev_attrs[] = { | 237 | static struct attribute *bdi_dev_attrs[] = { |
236 | __ATTR_RW(read_ahead_kb), | 238 | &dev_attr_read_ahead_kb.attr, |
237 | __ATTR_RW(min_ratio), | 239 | &dev_attr_min_ratio.attr, |
238 | __ATTR_RW(max_ratio), | 240 | &dev_attr_max_ratio.attr, |
239 | __ATTR_RO(stable_pages_required), | 241 | &dev_attr_stable_pages_required.attr, |
240 | __ATTR_NULL, | 242 | NULL, |
241 | }; | 243 | }; |
244 | ATTRIBUTE_GROUPS(bdi_dev); | ||
242 | 245 | ||
243 | static __init int bdi_class_init(void) | 246 | static __init int bdi_class_init(void) |
244 | { | 247 | { |
@@ -246,7 +249,7 @@ static __init int bdi_class_init(void) | |||
246 | if (IS_ERR(bdi_class)) | 249 | if (IS_ERR(bdi_class)) |
247 | return PTR_ERR(bdi_class); | 250 | return PTR_ERR(bdi_class); |
248 | 251 | ||
249 | bdi_class->dev_attrs = bdi_dev_attrs; | 252 | bdi_class->dev_groups = bdi_dev_groups; |
250 | bdi_debug_init(); | 253 | bdi_debug_init(); |
251 | return 0; | 254 | return 0; |
252 | } | 255 | } |
diff --git a/net/core/net-sysfs.c b/net/core/net-sysfs.c index 981fed397d1d..707c3134ddf2 100644 --- a/net/core/net-sysfs.c +++ b/net/core/net-sysfs.c | |||
@@ -60,12 +60,19 @@ static ssize_t format_##field(const struct net_device *net, char *buf) \ | |||
60 | { \ | 60 | { \ |
61 | return sprintf(buf, format_string, net->field); \ | 61 | return sprintf(buf, format_string, net->field); \ |
62 | } \ | 62 | } \ |
63 | static ssize_t show_##field(struct device *dev, \ | 63 | static ssize_t field##_show(struct device *dev, \ |
64 | struct device_attribute *attr, char *buf) \ | 64 | struct device_attribute *attr, char *buf) \ |
65 | { \ | 65 | { \ |
66 | return netdev_show(dev, attr, buf, format_##field); \ | 66 | return netdev_show(dev, attr, buf, format_##field); \ |
67 | } | 67 | } \ |
68 | |||
69 | #define NETDEVICE_SHOW_RO(field, format_string) \ | ||
70 | NETDEVICE_SHOW(field, format_string); \ | ||
71 | static DEVICE_ATTR_RO(field) | ||
68 | 72 | ||
73 | #define NETDEVICE_SHOW_RW(field, format_string) \ | ||
74 | NETDEVICE_SHOW(field, format_string); \ | ||
75 | static DEVICE_ATTR_RW(field) | ||
69 | 76 | ||
70 | /* use same locking and permission rules as SIF* ioctl's */ | 77 | /* use same locking and permission rules as SIF* ioctl's */ |
71 | static ssize_t netdev_store(struct device *dev, struct device_attribute *attr, | 78 | 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, | |||
96 | return ret; | 103 | return ret; |
97 | } | 104 | } |
98 | 105 | ||
99 | NETDEVICE_SHOW(dev_id, fmt_hex); | 106 | NETDEVICE_SHOW_RO(dev_id, fmt_hex); |
100 | NETDEVICE_SHOW(addr_assign_type, fmt_dec); | 107 | NETDEVICE_SHOW_RO(addr_assign_type, fmt_dec); |
101 | NETDEVICE_SHOW(addr_len, fmt_dec); | 108 | NETDEVICE_SHOW_RO(addr_len, fmt_dec); |
102 | NETDEVICE_SHOW(iflink, fmt_dec); | 109 | NETDEVICE_SHOW_RO(iflink, fmt_dec); |
103 | NETDEVICE_SHOW(ifindex, fmt_dec); | 110 | NETDEVICE_SHOW_RO(ifindex, fmt_dec); |
104 | NETDEVICE_SHOW(type, fmt_dec); | 111 | NETDEVICE_SHOW_RO(type, fmt_dec); |
105 | NETDEVICE_SHOW(link_mode, fmt_dec); | 112 | NETDEVICE_SHOW_RO(link_mode, fmt_dec); |
106 | 113 | ||
107 | /* use same locking rules as GIFHWADDR ioctl's */ | 114 | /* use same locking rules as GIFHWADDR ioctl's */ |
108 | static ssize_t show_address(struct device *dev, struct device_attribute *attr, | 115 | static ssize_t address_show(struct device *dev, struct device_attribute *attr, |
109 | char *buf) | 116 | char *buf) |
110 | { | 117 | { |
111 | struct net_device *net = to_net_dev(dev); | 118 | struct net_device *net = to_net_dev(dev); |
@@ -117,15 +124,17 @@ static ssize_t show_address(struct device *dev, struct device_attribute *attr, | |||
117 | read_unlock(&dev_base_lock); | 124 | read_unlock(&dev_base_lock); |
118 | return ret; | 125 | return ret; |
119 | } | 126 | } |
127 | static DEVICE_ATTR_RO(address); | ||
120 | 128 | ||
121 | static ssize_t show_broadcast(struct device *dev, | 129 | static ssize_t broadcast_show(struct device *dev, |
122 | struct device_attribute *attr, char *buf) | 130 | struct device_attribute *attr, char *buf) |
123 | { | 131 | { |
124 | struct net_device *net = to_net_dev(dev); | 132 | struct net_device *net = to_net_dev(dev); |
125 | if (dev_isalive(net)) | 133 | if (dev_isalive(net)) |
126 | return sysfs_format_mac(buf, net->broadcast, net->addr_len); | 134 | return sysfs_format_mac(buf, net->broadcast, net->addr_len); |
127 | return -EINVAL; | 135 | return -EINVAL; |
128 | } | 136 | } |
137 | static DEVICE_ATTR_RO(broadcast); | ||
129 | 138 | ||
130 | static int change_carrier(struct net_device *net, unsigned long new_carrier) | 139 | static int change_carrier(struct net_device *net, unsigned long new_carrier) |
131 | { | 140 | { |
@@ -134,13 +143,13 @@ static int change_carrier(struct net_device *net, unsigned long new_carrier) | |||
134 | return dev_change_carrier(net, (bool) new_carrier); | 143 | return dev_change_carrier(net, (bool) new_carrier); |
135 | } | 144 | } |
136 | 145 | ||
137 | static ssize_t store_carrier(struct device *dev, struct device_attribute *attr, | 146 | static ssize_t carrier_store(struct device *dev, struct device_attribute *attr, |
138 | const char *buf, size_t len) | 147 | const char *buf, size_t len) |
139 | { | 148 | { |
140 | return netdev_store(dev, attr, buf, len, change_carrier); | 149 | return netdev_store(dev, attr, buf, len, change_carrier); |
141 | } | 150 | } |
142 | 151 | ||
143 | static ssize_t show_carrier(struct device *dev, | 152 | static ssize_t carrier_show(struct device *dev, |
144 | struct device_attribute *attr, char *buf) | 153 | struct device_attribute *attr, char *buf) |
145 | { | 154 | { |
146 | struct net_device *netdev = to_net_dev(dev); | 155 | struct net_device *netdev = to_net_dev(dev); |
@@ -149,8 +158,9 @@ static ssize_t show_carrier(struct device *dev, | |||
149 | } | 158 | } |
150 | return -EINVAL; | 159 | return -EINVAL; |
151 | } | 160 | } |
161 | static DEVICE_ATTR_RW(carrier); | ||
152 | 162 | ||
153 | static ssize_t show_speed(struct device *dev, | 163 | static ssize_t speed_show(struct device *dev, |
154 | struct device_attribute *attr, char *buf) | 164 | struct device_attribute *attr, char *buf) |
155 | { | 165 | { |
156 | struct net_device *netdev = to_net_dev(dev); | 166 | struct net_device *netdev = to_net_dev(dev); |
@@ -167,8 +177,9 @@ static ssize_t show_speed(struct device *dev, | |||
167 | rtnl_unlock(); | 177 | rtnl_unlock(); |
168 | return ret; | 178 | return ret; |
169 | } | 179 | } |
180 | static DEVICE_ATTR_RO(speed); | ||
170 | 181 | ||
171 | static ssize_t show_duplex(struct device *dev, | 182 | static ssize_t duplex_show(struct device *dev, |
172 | struct device_attribute *attr, char *buf) | 183 | struct device_attribute *attr, char *buf) |
173 | { | 184 | { |
174 | struct net_device *netdev = to_net_dev(dev); | 185 | struct net_device *netdev = to_net_dev(dev); |
@@ -198,8 +209,9 @@ static ssize_t show_duplex(struct device *dev, | |||
198 | rtnl_unlock(); | 209 | rtnl_unlock(); |
199 | return ret; | 210 | return ret; |
200 | } | 211 | } |
212 | static DEVICE_ATTR_RO(duplex); | ||
201 | 213 | ||
202 | static ssize_t show_dormant(struct device *dev, | 214 | static ssize_t dormant_show(struct device *dev, |
203 | struct device_attribute *attr, char *buf) | 215 | struct device_attribute *attr, char *buf) |
204 | { | 216 | { |
205 | struct net_device *netdev = to_net_dev(dev); | 217 | struct net_device *netdev = to_net_dev(dev); |
@@ -209,6 +221,7 @@ static ssize_t show_dormant(struct device *dev, | |||
209 | 221 | ||
210 | return -EINVAL; | 222 | return -EINVAL; |
211 | } | 223 | } |
224 | static DEVICE_ATTR_RO(dormant); | ||
212 | 225 | ||
213 | static const char *const operstates[] = { | 226 | static const char *const operstates[] = { |
214 | "unknown", | 227 | "unknown", |
@@ -220,7 +233,7 @@ static const char *const operstates[] = { | |||
220 | "up" | 233 | "up" |
221 | }; | 234 | }; |
222 | 235 | ||
223 | static ssize_t show_operstate(struct device *dev, | 236 | static ssize_t operstate_show(struct device *dev, |
224 | struct device_attribute *attr, char *buf) | 237 | struct device_attribute *attr, char *buf) |
225 | { | 238 | { |
226 | const struct net_device *netdev = to_net_dev(dev); | 239 | const struct net_device *netdev = to_net_dev(dev); |
@@ -237,35 +250,33 @@ static ssize_t show_operstate(struct device *dev, | |||
237 | 250 | ||
238 | return sprintf(buf, "%s\n", operstates[operstate]); | 251 | return sprintf(buf, "%s\n", operstates[operstate]); |
239 | } | 252 | } |
253 | static DEVICE_ATTR_RO(operstate); | ||
240 | 254 | ||
241 | /* read-write attributes */ | 255 | /* read-write attributes */ |
242 | NETDEVICE_SHOW(mtu, fmt_dec); | ||
243 | 256 | ||
244 | static int change_mtu(struct net_device *net, unsigned long new_mtu) | 257 | static int change_mtu(struct net_device *net, unsigned long new_mtu) |
245 | { | 258 | { |
246 | return dev_set_mtu(net, (int) new_mtu); | 259 | return dev_set_mtu(net, (int) new_mtu); |
247 | } | 260 | } |
248 | 261 | ||
249 | static ssize_t store_mtu(struct device *dev, struct device_attribute *attr, | 262 | static ssize_t mtu_store(struct device *dev, struct device_attribute *attr, |
250 | const char *buf, size_t len) | 263 | const char *buf, size_t len) |
251 | { | 264 | { |
252 | return netdev_store(dev, attr, buf, len, change_mtu); | 265 | return netdev_store(dev, attr, buf, len, change_mtu); |
253 | } | 266 | } |
254 | 267 | NETDEVICE_SHOW_RW(mtu, fmt_dec); | |
255 | NETDEVICE_SHOW(flags, fmt_hex); | ||
256 | 268 | ||
257 | static int change_flags(struct net_device *net, unsigned long new_flags) | 269 | static int change_flags(struct net_device *net, unsigned long new_flags) |
258 | { | 270 | { |
259 | return dev_change_flags(net, (unsigned int) new_flags); | 271 | return dev_change_flags(net, (unsigned int) new_flags); |
260 | } | 272 | } |
261 | 273 | ||
262 | static ssize_t store_flags(struct device *dev, struct device_attribute *attr, | 274 | static ssize_t flags_store(struct device *dev, struct device_attribute *attr, |
263 | const char *buf, size_t len) | 275 | const char *buf, size_t len) |
264 | { | 276 | { |
265 | return netdev_store(dev, attr, buf, len, change_flags); | 277 | return netdev_store(dev, attr, buf, len, change_flags); |
266 | } | 278 | } |
267 | 279 | NETDEVICE_SHOW_RW(flags, fmt_hex); | |
268 | NETDEVICE_SHOW(tx_queue_len, fmt_ulong); | ||
269 | 280 | ||
270 | static int change_tx_queue_len(struct net_device *net, unsigned long new_len) | 281 | static int change_tx_queue_len(struct net_device *net, unsigned long new_len) |
271 | { | 282 | { |
@@ -273,7 +284,7 @@ static int change_tx_queue_len(struct net_device *net, unsigned long new_len) | |||
273 | return 0; | 284 | return 0; |
274 | } | 285 | } |
275 | 286 | ||
276 | static ssize_t store_tx_queue_len(struct device *dev, | 287 | static ssize_t tx_queue_len_store(struct device *dev, |
277 | struct device_attribute *attr, | 288 | struct device_attribute *attr, |
278 | const char *buf, size_t len) | 289 | const char *buf, size_t len) |
279 | { | 290 | { |
@@ -282,8 +293,9 @@ static ssize_t store_tx_queue_len(struct device *dev, | |||
282 | 293 | ||
283 | return netdev_store(dev, attr, buf, len, change_tx_queue_len); | 294 | return netdev_store(dev, attr, buf, len, change_tx_queue_len); |
284 | } | 295 | } |
296 | NETDEVICE_SHOW_RW(tx_queue_len, fmt_ulong); | ||
285 | 297 | ||
286 | static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr, | 298 | static ssize_t ifalias_store(struct device *dev, struct device_attribute *attr, |
287 | const char *buf, size_t len) | 299 | const char *buf, size_t len) |
288 | { | 300 | { |
289 | struct net_device *netdev = to_net_dev(dev); | 301 | struct net_device *netdev = to_net_dev(dev); |
@@ -306,7 +318,7 @@ static ssize_t store_ifalias(struct device *dev, struct device_attribute *attr, | |||
306 | return ret < 0 ? ret : len; | 318 | return ret < 0 ? ret : len; |
307 | } | 319 | } |
308 | 320 | ||
309 | static ssize_t show_ifalias(struct device *dev, | 321 | static ssize_t ifalias_show(struct device *dev, |
310 | struct device_attribute *attr, char *buf) | 322 | struct device_attribute *attr, char *buf) |
311 | { | 323 | { |
312 | const struct net_device *netdev = to_net_dev(dev); | 324 | const struct net_device *netdev = to_net_dev(dev); |
@@ -319,8 +331,7 @@ static ssize_t show_ifalias(struct device *dev, | |||
319 | rtnl_unlock(); | 331 | rtnl_unlock(); |
320 | return ret; | 332 | return ret; |
321 | } | 333 | } |
322 | 334 | static DEVICE_ATTR_RW(ifalias); | |
323 | NETDEVICE_SHOW(group, fmt_dec); | ||
324 | 335 | ||
325 | static int change_group(struct net_device *net, unsigned long new_group) | 336 | static int change_group(struct net_device *net, unsigned long new_group) |
326 | { | 337 | { |
@@ -328,35 +339,37 @@ static int change_group(struct net_device *net, unsigned long new_group) | |||
328 | return 0; | 339 | return 0; |
329 | } | 340 | } |
330 | 341 | ||
331 | static ssize_t store_group(struct device *dev, struct device_attribute *attr, | 342 | static ssize_t group_store(struct device *dev, struct device_attribute *attr, |
332 | const char *buf, size_t len) | 343 | const char *buf, size_t len) |
333 | { | 344 | { |
334 | return netdev_store(dev, attr, buf, len, change_group); | 345 | return netdev_store(dev, attr, buf, len, change_group); |
335 | } | 346 | } |
336 | 347 | NETDEVICE_SHOW(group, fmt_dec); | |
337 | static struct device_attribute net_class_attributes[] = { | 348 | static DEVICE_ATTR(netdev_group, S_IRUGO | S_IWUSR, group_show, group_store); |
338 | __ATTR(addr_assign_type, S_IRUGO, show_addr_assign_type, NULL), | 349 | |
339 | __ATTR(addr_len, S_IRUGO, show_addr_len, NULL), | 350 | static struct attribute *net_class_attrs[] = { |
340 | __ATTR(dev_id, S_IRUGO, show_dev_id, NULL), | 351 | &dev_attr_netdev_group.attr, |
341 | __ATTR(ifalias, S_IRUGO | S_IWUSR, show_ifalias, store_ifalias), | 352 | &dev_attr_type.attr, |
342 | __ATTR(iflink, S_IRUGO, show_iflink, NULL), | 353 | &dev_attr_dev_id.attr, |
343 | __ATTR(ifindex, S_IRUGO, show_ifindex, NULL), | 354 | &dev_attr_iflink.attr, |
344 | __ATTR(type, S_IRUGO, show_type, NULL), | 355 | &dev_attr_ifindex.attr, |
345 | __ATTR(link_mode, S_IRUGO, show_link_mode, NULL), | 356 | &dev_attr_addr_assign_type.attr, |
346 | __ATTR(address, S_IRUGO, show_address, NULL), | 357 | &dev_attr_addr_len.attr, |
347 | __ATTR(broadcast, S_IRUGO, show_broadcast, NULL), | 358 | &dev_attr_link_mode.attr, |
348 | __ATTR(carrier, S_IRUGO | S_IWUSR, show_carrier, store_carrier), | 359 | &dev_attr_address.attr, |
349 | __ATTR(speed, S_IRUGO, show_speed, NULL), | 360 | &dev_attr_broadcast.attr, |
350 | __ATTR(duplex, S_IRUGO, show_duplex, NULL), | 361 | &dev_attr_speed.attr, |
351 | __ATTR(dormant, S_IRUGO, show_dormant, NULL), | 362 | &dev_attr_duplex.attr, |
352 | __ATTR(operstate, S_IRUGO, show_operstate, NULL), | 363 | &dev_attr_dormant.attr, |
353 | __ATTR(mtu, S_IRUGO | S_IWUSR, show_mtu, store_mtu), | 364 | &dev_attr_operstate.attr, |
354 | __ATTR(flags, S_IRUGO | S_IWUSR, show_flags, store_flags), | 365 | &dev_attr_ifalias.attr, |
355 | __ATTR(tx_queue_len, S_IRUGO | S_IWUSR, show_tx_queue_len, | 366 | &dev_attr_carrier.attr, |
356 | store_tx_queue_len), | 367 | &dev_attr_mtu.attr, |
357 | __ATTR(netdev_group, S_IRUGO | S_IWUSR, show_group, store_group), | 368 | &dev_attr_flags.attr, |
358 | {} | 369 | &dev_attr_tx_queue_len.attr, |
370 | NULL, | ||
359 | }; | 371 | }; |
372 | ATTRIBUTE_GROUPS(net_class); | ||
360 | 373 | ||
361 | /* Show a given an attribute in the statistics group */ | 374 | /* Show a given an attribute in the statistics group */ |
362 | static ssize_t netstat_show(const struct device *d, | 375 | static ssize_t netstat_show(const struct device *d, |
@@ -382,13 +395,13 @@ static ssize_t netstat_show(const struct device *d, | |||
382 | 395 | ||
383 | /* generate a read-only statistics attribute */ | 396 | /* generate a read-only statistics attribute */ |
384 | #define NETSTAT_ENTRY(name) \ | 397 | #define NETSTAT_ENTRY(name) \ |
385 | static ssize_t show_##name(struct device *d, \ | 398 | static ssize_t name##_show(struct device *d, \ |
386 | struct device_attribute *attr, char *buf) \ | 399 | struct device_attribute *attr, char *buf) \ |
387 | { \ | 400 | { \ |
388 | return netstat_show(d, attr, buf, \ | 401 | return netstat_show(d, attr, buf, \ |
389 | offsetof(struct rtnl_link_stats64, name)); \ | 402 | offsetof(struct rtnl_link_stats64, name)); \ |
390 | } \ | 403 | } \ |
391 | static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) | 404 | static DEVICE_ATTR_RO(name) |
392 | 405 | ||
393 | NETSTAT_ENTRY(rx_packets); | 406 | NETSTAT_ENTRY(rx_packets); |
394 | NETSTAT_ENTRY(tx_packets); | 407 | NETSTAT_ENTRY(tx_packets); |
@@ -457,6 +470,9 @@ static struct attribute_group wireless_group = { | |||
457 | .attrs = wireless_attrs, | 470 | .attrs = wireless_attrs, |
458 | }; | 471 | }; |
459 | #endif | 472 | #endif |
473 | |||
474 | #else /* CONFIG_SYSFS */ | ||
475 | #define net_class_groups NULL | ||
460 | #endif /* CONFIG_SYSFS */ | 476 | #endif /* CONFIG_SYSFS */ |
461 | 477 | ||
462 | #ifdef CONFIG_RPS | 478 | #ifdef CONFIG_RPS |
@@ -1229,9 +1245,7 @@ static const void *net_namespace(struct device *d) | |||
1229 | static struct class net_class = { | 1245 | static struct class net_class = { |
1230 | .name = "net", | 1246 | .name = "net", |
1231 | .dev_release = netdev_release, | 1247 | .dev_release = netdev_release, |
1232 | #ifdef CONFIG_SYSFS | 1248 | .dev_groups = net_class_groups, |
1233 | .dev_attrs = net_class_attributes, | ||
1234 | #endif /* CONFIG_SYSFS */ | ||
1235 | .dev_uevent = netdev_uevent, | 1249 | .dev_uevent = netdev_uevent, |
1236 | .ns_type = &net_ns_type_operations, | 1250 | .ns_type = &net_ns_type_operations, |
1237 | .namespace = net_namespace, | 1251 | .namespace = net_namespace, |
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c index 13571eae6bae..ef56ab5b35fe 100644 --- a/net/ieee802154/wpan-class.c +++ b/net/ieee802154/wpan-class.c | |||
@@ -36,7 +36,8 @@ static ssize_t name ## _show(struct device *dev, \ | |||
36 | ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \ | 36 | ret = snprintf(buf, PAGE_SIZE, format_string "\n", args); \ |
37 | mutex_unlock(&phy->pib_lock); \ | 37 | mutex_unlock(&phy->pib_lock); \ |
38 | return ret; \ | 38 | return ret; \ |
39 | } | 39 | } \ |
40 | static DEVICE_ATTR_RO(name); | ||
40 | 41 | ||
41 | #define MASTER_SHOW(field, format_string) \ | 42 | #define MASTER_SHOW(field, format_string) \ |
42 | MASTER_SHOW_COMPLEX(field, format_string, phy->field) | 43 | MASTER_SHOW_COMPLEX(field, format_string, phy->field) |
@@ -66,15 +67,17 @@ static ssize_t channels_supported_show(struct device *dev, | |||
66 | mutex_unlock(&phy->pib_lock); | 67 | mutex_unlock(&phy->pib_lock); |
67 | return len; | 68 | return len; |
68 | } | 69 | } |
69 | 70 | static DEVICE_ATTR_RO(channels_supported); | |
70 | static struct device_attribute pmib_attrs[] = { | 71 | |
71 | __ATTR_RO(current_channel), | 72 | static struct attribute *pmib_attrs[] = { |
72 | __ATTR_RO(current_page), | 73 | &dev_attr_current_channel.attr, |
73 | __ATTR_RO(channels_supported), | 74 | &dev_attr_current_page.attr, |
74 | __ATTR_RO(transmit_power), | 75 | &dev_attr_channels_supported.attr, |
75 | __ATTR_RO(cca_mode), | 76 | &dev_attr_transmit_power.attr, |
76 | {}, | 77 | &dev_attr_cca_mode.attr, |
78 | NULL, | ||
77 | }; | 79 | }; |
80 | ATTRIBUTE_GROUPS(pmib); | ||
78 | 81 | ||
79 | static void wpan_phy_release(struct device *d) | 82 | static void wpan_phy_release(struct device *d) |
80 | { | 83 | { |
@@ -85,7 +88,7 @@ static void wpan_phy_release(struct device *d) | |||
85 | static struct class wpan_phy_class = { | 88 | static struct class wpan_phy_class = { |
86 | .name = "ieee802154", | 89 | .name = "ieee802154", |
87 | .dev_release = wpan_phy_release, | 90 | .dev_release = wpan_phy_release, |
88 | .dev_attrs = pmib_attrs, | 91 | .dev_groups = pmib_groups, |
89 | }; | 92 | }; |
90 | 93 | ||
91 | static DEFINE_MUTEX(wpan_phy_mutex); | 94 | static DEFINE_MUTEX(wpan_phy_mutex); |
diff --git a/net/rfkill/core.c b/net/rfkill/core.c index 1cec5e4f3a5e..1bacc1079942 100644 --- a/net/rfkill/core.c +++ b/net/rfkill/core.c | |||
@@ -576,14 +576,14 @@ void rfkill_set_states(struct rfkill *rfkill, bool sw, bool hw) | |||
576 | } | 576 | } |
577 | EXPORT_SYMBOL(rfkill_set_states); | 577 | EXPORT_SYMBOL(rfkill_set_states); |
578 | 578 | ||
579 | static ssize_t rfkill_name_show(struct device *dev, | 579 | static ssize_t name_show(struct device *dev, struct device_attribute *attr, |
580 | struct device_attribute *attr, | 580 | char *buf) |
581 | char *buf) | ||
582 | { | 581 | { |
583 | struct rfkill *rfkill = to_rfkill(dev); | 582 | struct rfkill *rfkill = to_rfkill(dev); |
584 | 583 | ||
585 | return sprintf(buf, "%s\n", rfkill->name); | 584 | return sprintf(buf, "%s\n", rfkill->name); |
586 | } | 585 | } |
586 | static DEVICE_ATTR_RO(name); | ||
587 | 587 | ||
588 | static const char *rfkill_get_type_str(enum rfkill_type type) | 588 | static const char *rfkill_get_type_str(enum rfkill_type type) |
589 | { | 589 | { |
@@ -611,54 +611,52 @@ static const char *rfkill_get_type_str(enum rfkill_type type) | |||
611 | } | 611 | } |
612 | } | 612 | } |
613 | 613 | ||
614 | static ssize_t rfkill_type_show(struct device *dev, | 614 | static ssize_t type_show(struct device *dev, struct device_attribute *attr, |
615 | struct device_attribute *attr, | 615 | char *buf) |
616 | char *buf) | ||
617 | { | 616 | { |
618 | struct rfkill *rfkill = to_rfkill(dev); | 617 | struct rfkill *rfkill = to_rfkill(dev); |
619 | 618 | ||
620 | return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type)); | 619 | return sprintf(buf, "%s\n", rfkill_get_type_str(rfkill->type)); |
621 | } | 620 | } |
621 | static DEVICE_ATTR_RO(type); | ||
622 | 622 | ||
623 | static ssize_t rfkill_idx_show(struct device *dev, | 623 | static ssize_t index_show(struct device *dev, struct device_attribute *attr, |
624 | struct device_attribute *attr, | 624 | char *buf) |
625 | char *buf) | ||
626 | { | 625 | { |
627 | struct rfkill *rfkill = to_rfkill(dev); | 626 | struct rfkill *rfkill = to_rfkill(dev); |
628 | 627 | ||
629 | return sprintf(buf, "%d\n", rfkill->idx); | 628 | return sprintf(buf, "%d\n", rfkill->idx); |
630 | } | 629 | } |
630 | static DEVICE_ATTR_RO(index); | ||
631 | 631 | ||
632 | static ssize_t rfkill_persistent_show(struct device *dev, | 632 | static ssize_t persistent_show(struct device *dev, |
633 | struct device_attribute *attr, | 633 | struct device_attribute *attr, char *buf) |
634 | char *buf) | ||
635 | { | 634 | { |
636 | struct rfkill *rfkill = to_rfkill(dev); | 635 | struct rfkill *rfkill = to_rfkill(dev); |
637 | 636 | ||
638 | return sprintf(buf, "%d\n", rfkill->persistent); | 637 | return sprintf(buf, "%d\n", rfkill->persistent); |
639 | } | 638 | } |
639 | static DEVICE_ATTR_RO(persistent); | ||
640 | 640 | ||
641 | static ssize_t rfkill_hard_show(struct device *dev, | 641 | static ssize_t hard_show(struct device *dev, struct device_attribute *attr, |
642 | struct device_attribute *attr, | 642 | char *buf) |
643 | char *buf) | ||
644 | { | 643 | { |
645 | struct rfkill *rfkill = to_rfkill(dev); | 644 | struct rfkill *rfkill = to_rfkill(dev); |
646 | 645 | ||
647 | return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_HW) ? 1 : 0 ); | 646 | return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_HW) ? 1 : 0 ); |
648 | } | 647 | } |
648 | static DEVICE_ATTR_RO(hard); | ||
649 | 649 | ||
650 | static ssize_t rfkill_soft_show(struct device *dev, | 650 | static ssize_t soft_show(struct device *dev, struct device_attribute *attr, |
651 | struct device_attribute *attr, | 651 | char *buf) |
652 | char *buf) | ||
653 | { | 652 | { |
654 | struct rfkill *rfkill = to_rfkill(dev); | 653 | struct rfkill *rfkill = to_rfkill(dev); |
655 | 654 | ||
656 | return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0 ); | 655 | return sprintf(buf, "%d\n", (rfkill->state & RFKILL_BLOCK_SW) ? 1 : 0 ); |
657 | } | 656 | } |
658 | 657 | ||
659 | static ssize_t rfkill_soft_store(struct device *dev, | 658 | static ssize_t soft_store(struct device *dev, struct device_attribute *attr, |
660 | struct device_attribute *attr, | 659 | const char *buf, size_t count) |
661 | const char *buf, size_t count) | ||
662 | { | 660 | { |
663 | struct rfkill *rfkill = to_rfkill(dev); | 661 | struct rfkill *rfkill = to_rfkill(dev); |
664 | unsigned long state; | 662 | unsigned long state; |
@@ -680,6 +678,7 @@ static ssize_t rfkill_soft_store(struct device *dev, | |||
680 | 678 | ||
681 | return count; | 679 | return count; |
682 | } | 680 | } |
681 | static DEVICE_ATTR_RW(soft); | ||
683 | 682 | ||
684 | static u8 user_state_from_blocked(unsigned long state) | 683 | static u8 user_state_from_blocked(unsigned long state) |
685 | { | 684 | { |
@@ -691,18 +690,16 @@ static u8 user_state_from_blocked(unsigned long state) | |||
691 | return RFKILL_USER_STATE_UNBLOCKED; | 690 | return RFKILL_USER_STATE_UNBLOCKED; |
692 | } | 691 | } |
693 | 692 | ||
694 | static ssize_t rfkill_state_show(struct device *dev, | 693 | static ssize_t state_show(struct device *dev, struct device_attribute *attr, |
695 | struct device_attribute *attr, | 694 | char *buf) |
696 | char *buf) | ||
697 | { | 695 | { |
698 | struct rfkill *rfkill = to_rfkill(dev); | 696 | struct rfkill *rfkill = to_rfkill(dev); |
699 | 697 | ||
700 | return sprintf(buf, "%d\n", user_state_from_blocked(rfkill->state)); | 698 | return sprintf(buf, "%d\n", user_state_from_blocked(rfkill->state)); |
701 | } | 699 | } |
702 | 700 | ||
703 | static ssize_t rfkill_state_store(struct device *dev, | 701 | static ssize_t state_store(struct device *dev, struct device_attribute *attr, |
704 | struct device_attribute *attr, | 702 | const char *buf, size_t count) |
705 | const char *buf, size_t count) | ||
706 | { | 703 | { |
707 | struct rfkill *rfkill = to_rfkill(dev); | 704 | struct rfkill *rfkill = to_rfkill(dev); |
708 | unsigned long state; | 705 | unsigned long state; |
@@ -725,32 +722,27 @@ static ssize_t rfkill_state_store(struct device *dev, | |||
725 | 722 | ||
726 | return count; | 723 | return count; |
727 | } | 724 | } |
725 | static DEVICE_ATTR_RW(state); | ||
728 | 726 | ||
729 | static ssize_t rfkill_claim_show(struct device *dev, | 727 | static ssize_t claim_show(struct device *dev, struct device_attribute *attr, |
730 | struct device_attribute *attr, | 728 | char *buf) |
731 | char *buf) | ||
732 | { | 729 | { |
733 | return sprintf(buf, "%d\n", 0); | 730 | return sprintf(buf, "%d\n", 0); |
734 | } | 731 | } |
735 | 732 | static DEVICE_ATTR_RO(claim); | |
736 | static ssize_t rfkill_claim_store(struct device *dev, | 733 | |
737 | struct device_attribute *attr, | 734 | static struct attribute *rfkill_dev_attrs[] = { |
738 | const char *buf, size_t count) | 735 | &dev_attr_name.attr, |
739 | { | 736 | &dev_attr_type.attr, |
740 | return -EOPNOTSUPP; | 737 | &dev_attr_index.attr, |
741 | } | 738 | &dev_attr_persistent.attr, |
742 | 739 | &dev_attr_state.attr, | |
743 | static struct device_attribute rfkill_dev_attrs[] = { | 740 | &dev_attr_claim.attr, |
744 | __ATTR(name, S_IRUGO, rfkill_name_show, NULL), | 741 | &dev_attr_soft.attr, |
745 | __ATTR(type, S_IRUGO, rfkill_type_show, NULL), | 742 | &dev_attr_hard.attr, |
746 | __ATTR(index, S_IRUGO, rfkill_idx_show, NULL), | 743 | NULL, |
747 | __ATTR(persistent, S_IRUGO, rfkill_persistent_show, NULL), | ||
748 | __ATTR(state, S_IRUGO|S_IWUSR, rfkill_state_show, rfkill_state_store), | ||
749 | __ATTR(claim, S_IRUGO|S_IWUSR, rfkill_claim_show, rfkill_claim_store), | ||
750 | __ATTR(soft, S_IRUGO|S_IWUSR, rfkill_soft_show, rfkill_soft_store), | ||
751 | __ATTR(hard, S_IRUGO, rfkill_hard_show, NULL), | ||
752 | __ATTR_NULL | ||
753 | }; | 744 | }; |
745 | ATTRIBUTE_GROUPS(rfkill_dev); | ||
754 | 746 | ||
755 | static void rfkill_release(struct device *dev) | 747 | static void rfkill_release(struct device *dev) |
756 | { | 748 | { |
@@ -830,7 +822,7 @@ static int rfkill_resume(struct device *dev) | |||
830 | static struct class rfkill_class = { | 822 | static struct class rfkill_class = { |
831 | .name = "rfkill", | 823 | .name = "rfkill", |
832 | .dev_release = rfkill_release, | 824 | .dev_release = rfkill_release, |
833 | .dev_attrs = rfkill_dev_attrs, | 825 | .dev_groups = rfkill_dev_groups, |
834 | .dev_uevent = rfkill_dev_uevent, | 826 | .dev_uevent = rfkill_dev_uevent, |
835 | .suspend = rfkill_suspend, | 827 | .suspend = rfkill_suspend, |
836 | .resume = rfkill_resume, | 828 | .resume = rfkill_resume, |
diff --git a/net/wireless/sysfs.c b/net/wireless/sysfs.c index a23253e06358..9ee6bc1a7610 100644 --- a/net/wireless/sysfs.c +++ b/net/wireless/sysfs.c | |||
@@ -30,7 +30,8 @@ static ssize_t name ## _show(struct device *dev, \ | |||
30 | char *buf) \ | 30 | char *buf) \ |
31 | { \ | 31 | { \ |
32 | return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ | 32 | return sprintf(buf, fmt "\n", dev_to_rdev(dev)->member); \ |
33 | } | 33 | } \ |
34 | static DEVICE_ATTR_RO(name) | ||
34 | 35 | ||
35 | SHOW_FMT(index, "%d", wiphy_idx); | 36 | SHOW_FMT(index, "%d", wiphy_idx); |
36 | SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); | 37 | SHOW_FMT(macaddress, "%pM", wiphy.perm_addr); |
@@ -42,7 +43,7 @@ static ssize_t name_show(struct device *dev, | |||
42 | struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy; | 43 | struct wiphy *wiphy = &dev_to_rdev(dev)->wiphy; |
43 | return sprintf(buf, "%s\n", dev_name(&wiphy->dev)); | 44 | return sprintf(buf, "%s\n", dev_name(&wiphy->dev)); |
44 | } | 45 | } |
45 | 46 | static DEVICE_ATTR_RO(name); | |
46 | 47 | ||
47 | static ssize_t addresses_show(struct device *dev, | 48 | static ssize_t addresses_show(struct device *dev, |
48 | struct device_attribute *attr, | 49 | struct device_attribute *attr, |
@@ -60,15 +61,17 @@ static ssize_t addresses_show(struct device *dev, | |||
60 | 61 | ||
61 | return buf - start; | 62 | return buf - start; |
62 | } | 63 | } |
63 | 64 | static DEVICE_ATTR_RO(addresses); | |
64 | static struct device_attribute ieee80211_dev_attrs[] = { | 65 | |
65 | __ATTR_RO(index), | 66 | static struct attribute *ieee80211_attrs[] = { |
66 | __ATTR_RO(macaddress), | 67 | &dev_attr_index.attr, |
67 | __ATTR_RO(address_mask), | 68 | &dev_attr_macaddress.attr, |
68 | __ATTR_RO(addresses), | 69 | &dev_attr_address_mask.attr, |
69 | __ATTR_RO(name), | 70 | &dev_attr_addresses.attr, |
70 | {} | 71 | &dev_attr_name.attr, |
72 | NULL, | ||
71 | }; | 73 | }; |
74 | ATTRIBUTE_GROUPS(ieee80211); | ||
72 | 75 | ||
73 | static void wiphy_dev_release(struct device *dev) | 76 | static void wiphy_dev_release(struct device *dev) |
74 | { | 77 | { |
@@ -146,7 +149,7 @@ struct class ieee80211_class = { | |||
146 | .name = "ieee80211", | 149 | .name = "ieee80211", |
147 | .owner = THIS_MODULE, | 150 | .owner = THIS_MODULE, |
148 | .dev_release = wiphy_dev_release, | 151 | .dev_release = wiphy_dev_release, |
149 | .dev_attrs = ieee80211_dev_attrs, | 152 | .dev_groups = ieee80211_groups, |
150 | .dev_uevent = wiphy_uevent, | 153 | .dev_uevent = wiphy_uevent, |
151 | #ifdef CONFIG_PM | 154 | #ifdef CONFIG_PM |
152 | .suspend = wiphy_suspend, | 155 | .suspend = wiphy_suspend, |