11
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
13
* GNU General Public License for more details.
14
+ *
15
+ * TODO:
16
+ * - Rework topology
17
+ * - s/chip_id/chip_loc
18
+ * - s/cfam/chip (cfam_id -> chip_id etc...)
14
19
*/
15
20
16
21
#include <linux/crc4.h>
21
26
#include <linux/of.h>
22
27
#include <linux/slab.h>
23
28
#include <linux/bitops.h>
29
+ #include <linux/cdev.h>
30
+ #include <linux/fs.h>
31
+ #include <linux/uaccess.h>
24
32
25
33
#include "fsi-master.h"
26
34
@@ -78,8 +86,11 @@ static DEFINE_IDA(master_ida);
78
86
struct fsi_slave {
79
87
struct device dev ;
80
88
struct fsi_master * master ;
81
- int id ;
82
- int link ;
89
+ struct cdev cdev ;
90
+ int cdev_idx ;
91
+ int id ; /* FSI address */
92
+ int link ; /* FSI link# */
93
+ u32 cfam_id ;
83
94
int chip_id ;
84
95
uint32_t size ; /* size of slave address space */
85
96
u8 t_send_delay ;
@@ -607,29 +618,6 @@ static const struct bin_attribute fsi_slave_raw_attr = {
607
618
.write = fsi_slave_sysfs_raw_write ,
608
619
};
609
620
610
- static ssize_t fsi_slave_sysfs_term_write (struct file * file ,
611
- struct kobject * kobj , struct bin_attribute * attr ,
612
- char * buf , loff_t off , size_t count )
613
- {
614
- struct fsi_slave * slave = to_fsi_slave (kobj_to_dev (kobj ));
615
- struct fsi_master * master = slave -> master ;
616
-
617
- if (!master -> term )
618
- return - ENODEV ;
619
-
620
- master -> term (master , slave -> link , slave -> id );
621
- return count ;
622
- }
623
-
624
- static const struct bin_attribute fsi_slave_term_attr = {
625
- .attr = {
626
- .name = "term" ,
627
- .mode = 0200 ,
628
- },
629
- .size = 0 ,
630
- .write = fsi_slave_sysfs_term_write ,
631
- };
632
-
633
621
static void fsi_slave_release (struct device * dev )
634
622
{
635
623
struct fsi_slave * slave = to_fsi_slave (dev );
@@ -682,6 +670,127 @@ static struct device_node *fsi_slave_find_of_node(struct fsi_master *master,
682
670
return NULL ;
683
671
}
684
672
673
+ static ssize_t cfam_read (struct file * filep , char __user * buf , size_t count ,
674
+ loff_t * offset )
675
+ {
676
+ struct fsi_slave * slave = filep -> private_data ;
677
+ size_t total_len , read_len ;
678
+ loff_t off = * offset ;
679
+ ssize_t rc ;
680
+
681
+ if (off < 0 )
682
+ return - EINVAL ;
683
+
684
+ if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff )
685
+ return - EINVAL ;
686
+
687
+ for (total_len = 0 ; total_len < count ; total_len += read_len ) {
688
+ __be32 data ;
689
+
690
+ read_len = min_t (size_t , count , 4 );
691
+ read_len -= off & 0x3 ;
692
+
693
+ rc = fsi_slave_read (slave , off , & data , read_len );
694
+ if (rc )
695
+ goto fail ;
696
+ rc = copy_to_user (buf + total_len , & data , read_len );
697
+ if (rc ) {
698
+ rc = - EFAULT ;
699
+ goto fail ;
700
+ }
701
+ off += read_len ;
702
+ }
703
+ rc = count ;
704
+ fail :
705
+ * offset = off ;
706
+ return count ;
707
+ }
708
+
709
+ static ssize_t cfam_write (struct file * filep , const char __user * buf ,
710
+ size_t count , loff_t * offset )
711
+ {
712
+ struct fsi_slave * slave = filep -> private_data ;
713
+ size_t total_len , write_len ;
714
+ loff_t off = * offset ;
715
+ ssize_t rc ;
716
+
717
+
718
+ if (off < 0 )
719
+ return - EINVAL ;
720
+
721
+ if (off > 0xffffffff || count > 0xffffffff || off + count > 0xffffffff )
722
+ return - EINVAL ;
723
+
724
+ for (total_len = 0 ; total_len < count ; total_len += write_len ) {
725
+ __be32 data ;
726
+
727
+ write_len = min_t (size_t , count , 4 );
728
+ write_len -= off & 0x3 ;
729
+
730
+ rc = copy_from_user (& data , buf + total_len , write_len );
731
+ if (rc ) {
732
+ rc = - EFAULT ;
733
+ goto fail ;
734
+ }
735
+ rc = fsi_slave_write (slave , off , & data , write_len );
736
+ if (rc )
737
+ goto fail ;
738
+ off += write_len ;
739
+ }
740
+ rc = count ;
741
+ fail :
742
+ * offset = off ;
743
+ return count ;
744
+ }
745
+
746
+ static loff_t cfam_llseek (struct file * file , loff_t offset , int whence )
747
+ {
748
+ switch (whence ) {
749
+ case SEEK_CUR :
750
+ break ;
751
+ case SEEK_SET :
752
+ file -> f_pos = offset ;
753
+ break ;
754
+ default :
755
+ return - EINVAL ;
756
+ }
757
+
758
+ return offset ;
759
+ }
760
+
761
+ static int cfam_open (struct inode * inode , struct file * file )
762
+ {
763
+ struct fsi_slave * slave = container_of (inode -> i_cdev , struct fsi_slave , cdev );
764
+
765
+ file -> private_data = slave ;
766
+
767
+ return 0 ;
768
+ }
769
+
770
+ static const struct file_operations cfam_fops = {
771
+ .owner = THIS_MODULE ,
772
+ .open = cfam_open ,
773
+ .llseek = cfam_llseek ,
774
+ .read = cfam_read ,
775
+ .write = cfam_write ,
776
+ };
777
+
778
+ static ssize_t send_term_store (struct device * dev ,
779
+ struct device_attribute * attr ,
780
+ const char * buf , size_t count )
781
+ {
782
+ struct fsi_slave * slave = to_fsi_slave (dev );
783
+ struct fsi_master * master = slave -> master ;
784
+
785
+ if (!master -> term )
786
+ return - ENODEV ;
787
+
788
+ master -> term (master , slave -> link , slave -> id );
789
+ return count ;
790
+ }
791
+
792
+ static DEVICE_ATTR_WO (send_term );
793
+
685
794
static ssize_t slave_send_echo_show (struct device * dev ,
686
795
struct device_attribute * attr ,
687
796
char * buf )
@@ -737,6 +846,52 @@ static ssize_t chip_id_show(struct device *dev,
737
846
738
847
static DEVICE_ATTR_RO (chip_id );
739
848
849
+ static ssize_t cfam_id_show (struct device * dev ,
850
+ struct device_attribute * attr ,
851
+ char * buf )
852
+ {
853
+ struct fsi_slave * slave = to_fsi_slave (dev );
854
+
855
+ return sprintf (buf , "0x%x\n" , slave -> cfam_id );
856
+ }
857
+
858
+ static DEVICE_ATTR_RO (cfam_id );
859
+
860
+ static struct attribute * cfam_attr [] = {
861
+ & dev_attr_send_echo_delays .attr ,
862
+ & dev_attr_chip_id .attr ,
863
+ & dev_attr_cfam_id .attr ,
864
+ & dev_attr_send_term .attr ,
865
+ NULL ,
866
+ };
867
+
868
+ static const struct attribute_group cfam_attr_group = {
869
+ .attrs = cfam_attr ,
870
+ };
871
+
872
+ static const struct attribute_group * cfam_attr_groups [] = {
873
+ & cfam_attr_group ,
874
+ NULL ,
875
+ };
876
+
877
+ static char * cfam_devnode (struct device * dev , umode_t * mode ,
878
+ kuid_t * uid , kgid_t * gid )
879
+ {
880
+ struct fsi_slave * slave = to_fsi_slave (dev );
881
+
882
+ #ifdef CONFIG_FSI_NEW_DEV_NODE
883
+ return kasprintf (GFP_KERNEL , "fsi/cfam%d" , slave -> cdev_idx );
884
+ #else
885
+ return kasprintf (GFP_KERNEL , "cfam%d" , slave -> cdev_idx );
886
+ #endif
887
+ }
888
+
889
+ static const struct device_type cfam_type = {
890
+ .name = "cfam" ,
891
+ .devnode = cfam_devnode ,
892
+ .groups = cfam_attr_groups
893
+ };
894
+
740
895
static char * fsi_cdev_devnode (struct device * dev , umode_t * mode ,
741
896
kuid_t * uid , kgid_t * gid )
742
897
{
@@ -808,7 +963,7 @@ EXPORT_SYMBOL_GPL(fsi_free_minor);
808
963
809
964
static int fsi_slave_init (struct fsi_master * master , int link , uint8_t id )
810
965
{
811
- uint32_t chip_id ;
966
+ uint32_t cfam_id ;
812
967
struct fsi_slave * slave ;
813
968
uint8_t crc ;
814
969
__be32 data , llmode ;
@@ -826,17 +981,17 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
826
981
link , id , rc );
827
982
return - ENODEV ;
828
983
}
829
- chip_id = be32_to_cpu (data );
984
+ cfam_id = be32_to_cpu (data );
830
985
831
- crc = crc4 (0 , chip_id , 32 );
986
+ crc = crc4 (0 , cfam_id , 32 );
832
987
if (crc ) {
833
- dev_warn (& master -> dev , "slave %02x:%02x invalid chip id CRC!\n" ,
988
+ dev_warn (& master -> dev , "slave %02x:%02x invalid cfam id CRC!\n" ,
834
989
link , id );
835
990
return - EIO ;
836
991
}
837
992
838
993
dev_dbg (& master -> dev , "fsi: found chip %08x at %02x:%02x:%02x\n" ,
839
- chip_id , master -> idx , link , id );
994
+ cfam_id , master -> idx , link , id );
840
995
841
996
/* If we're behind a master that doesn't provide a self-running bus
842
997
* clock, put the slave into async mode
@@ -859,10 +1014,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
859
1014
if (!slave )
860
1015
return - ENOMEM ;
861
1016
862
- slave -> master = master ;
1017
+ dev_set_name (& slave -> dev , "slave@%02x:%02x" , link , id );
1018
+ slave -> dev .type = & cfam_type ;
863
1019
slave -> dev .parent = & master -> dev ;
864
1020
slave -> dev .of_node = fsi_slave_find_of_node (master , link , id );
865
1021
slave -> dev .release = fsi_slave_release ;
1022
+ device_initialize (& slave -> dev );
1023
+ slave -> cfam_id = cfam_id ;
1024
+ slave -> master = master ;
866
1025
slave -> link = link ;
867
1026
slave -> id = id ;
868
1027
slave -> size = FSI_SLAVE_SIZE_23b ;
@@ -877,6 +1036,21 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
877
1036
slave -> chip_id = prop ;
878
1037
879
1038
}
1039
+
1040
+ /* Allocate a minor in the FSI space */
1041
+ rc = __fsi_get_new_minor (slave , fsi_dev_cfam , & slave -> dev .devt ,
1042
+ & slave -> cdev_idx );
1043
+ if (rc )
1044
+ goto err_free ;
1045
+
1046
+ /* Create chardev for userspace access */
1047
+ cdev_init (& slave -> cdev , & cfam_fops );
1048
+ rc = cdev_device_add (& slave -> cdev , & slave -> dev );
1049
+ if (rc ) {
1050
+ dev_err (& slave -> dev , "Error %d creating slave device\n" , rc );
1051
+ goto err_free ;
1052
+ }
1053
+
880
1054
rc = fsi_slave_set_smode (slave );
881
1055
if (rc ) {
882
1056
dev_warn (& master -> dev ,
@@ -890,37 +1064,22 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id)
890
1064
slave -> t_send_delay ,
891
1065
slave -> t_echo_delay );
892
1066
893
- dev_set_name (& slave -> dev , "slave@%02x:%02x" , link , id );
894
- rc = device_register (& slave -> dev );
895
- if (rc < 0 ) {
896
- dev_warn (& master -> dev , "failed to create slave device: %d\n" ,
897
- rc );
898
- put_device (& slave -> dev );
899
- return rc ;
900
- }
901
-
1067
+ /* Legacy raw file -> to be removed */
902
1068
rc = device_create_bin_file (& slave -> dev , & fsi_slave_raw_attr );
903
1069
if (rc )
904
1070
dev_warn (& slave -> dev , "failed to create raw attr: %d\n" , rc );
905
1071
906
- rc = device_create_bin_file (& slave -> dev , & fsi_slave_term_attr );
907
- if (rc )
908
- dev_warn (& slave -> dev , "failed to create term attr: %d\n" , rc );
909
-
910
- rc = device_create_file (& slave -> dev , & dev_attr_send_echo_delays );
911
- if (rc )
912
- dev_warn (& slave -> dev , "failed to create delay attr: %d\n" , rc );
913
-
914
- rc = device_create_file (& slave -> dev , & dev_attr_chip_id );
915
- if (rc )
916
- dev_warn (& slave -> dev , "failed to create chip id: %d\n" , rc );
917
1072
918
1073
rc = fsi_slave_scan (slave );
919
1074
if (rc )
920
1075
dev_dbg (& master -> dev , "failed during slave scan with: %d\n" ,
921
1076
rc );
922
1077
923
1078
return rc ;
1079
+
1080
+ err_free :
1081
+ put_device (& slave -> dev );
1082
+ return rc ;
924
1083
}
925
1084
926
1085
/* FSI master support */
@@ -1029,7 +1188,10 @@ static int fsi_slave_remove_device(struct device *dev, void *arg)
1029
1188
1030
1189
static int fsi_master_remove_slave (struct device * dev , void * arg )
1031
1190
{
1191
+ struct fsi_slave * slave = to_fsi_slave (dev );
1192
+
1032
1193
device_for_each_child (dev , NULL , fsi_slave_remove_device );
1194
+ cdev_device_del (& slave -> cdev , & slave -> dev );
1033
1195
put_device (dev );
1034
1196
return 0 ;
1035
1197
}
0 commit comments