~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise-security

« back to all changes in this revision

Viewing changes to drivers/hwmon/lm78.c

  • Committer: Package Import Robot
  • Author(s): Paolo Pisati, Paolo Pisati
  • Date: 2011-12-06 15:56:07 UTC
  • Revision ID: package-import@ubuntu.com-20111206155607-pcf44kv5fmhk564f
Tags: 3.2.0-1401.1
[ Paolo Pisati ]

* Rebased on top of Ubuntu-3.2.0-3.8
* Tilt-tracking @ ef2487af4bb15bdd0689631774b5a5e3a59f74e2
* Delete debian.ti-omap4/control, it shoudln't be tracked
* Fix architecture spelling (s/armel/armhf/)
* [Config] Update configs following 3.2 import
* [Config] Fix compilation: disable CODA and ARCH_OMAP3
* [Config] Fix compilation: disable Ethernet Faraday
* Update series to precise

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
    lm78.c - Part of lm_sensors, Linux kernel modules for hardware
3
3
             monitoring
4
4
    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
5
 
    Copyright (c) 2007        Jean Delvare <khali@linux-fr.org>
 
5
    Copyright (c) 2007, 2011  Jean Delvare <khali@linux-fr.org>
6
6
 
7
7
    This program is free software; you can redistribute it and/or modify
8
8
    it under the terms of the GNU General Public License as published by
26
26
#include <linux/slab.h>
27
27
#include <linux/jiffies.h>
28
28
#include <linux/i2c.h>
29
 
#include <linux/platform_device.h>
30
 
#include <linux/ioport.h>
31
29
#include <linux/hwmon.h>
32
30
#include <linux/hwmon-vid.h>
33
31
#include <linux/hwmon-sysfs.h>
34
32
#include <linux/err.h>
35
33
#include <linux/mutex.h>
 
34
 
 
35
#ifdef CONFIG_ISA
 
36
#include <linux/platform_device.h>
 
37
#include <linux/ioport.h>
36
38
#include <linux/io.h>
37
 
 
38
 
/* ISA device, if found */
39
 
static struct platform_device *pdev;
 
39
#endif
40
40
 
41
41
/* Addresses to scan */
42
42
static const unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
43
43
                                                0x2e, 0x2f, I2C_CLIENT_END };
44
 
static unsigned short isa_address = 0x290;
45
 
 
46
44
enum chips { lm78, lm79 };
47
45
 
48
46
/* Many LM78 constants specified below */
143
141
};
144
142
 
145
143
 
146
 
static int lm78_i2c_detect(struct i2c_client *client,
147
 
                           struct i2c_board_info *info);
148
 
static int lm78_i2c_probe(struct i2c_client *client,
149
 
                          const struct i2c_device_id *id);
150
 
static int lm78_i2c_remove(struct i2c_client *client);
151
 
 
152
 
static int __devinit lm78_isa_probe(struct platform_device *pdev);
153
 
static int __devexit lm78_isa_remove(struct platform_device *pdev);
154
 
 
155
144
static int lm78_read_value(struct lm78_data *data, u8 reg);
156
145
static int lm78_write_value(struct lm78_data *data, u8 reg, u8 value);
157
146
static struct lm78_data *lm78_update_device(struct device *dev);
158
147
static void lm78_init_device(struct lm78_data *data);
159
148
 
160
149
 
161
 
static const struct i2c_device_id lm78_i2c_id[] = {
162
 
        { "lm78", lm78 },
163
 
        { "lm79", lm79 },
164
 
        { }
165
 
};
166
 
MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
167
 
 
168
 
static struct i2c_driver lm78_driver = {
169
 
        .class          = I2C_CLASS_HWMON,
170
 
        .driver = {
171
 
                .name   = "lm78",
172
 
        },
173
 
        .probe          = lm78_i2c_probe,
174
 
        .remove         = lm78_i2c_remove,
175
 
        .id_table       = lm78_i2c_id,
176
 
        .detect         = lm78_i2c_detect,
177
 
        .address_list   = normal_i2c,
178
 
};
179
 
 
180
 
static struct platform_driver lm78_isa_driver = {
181
 
        .driver = {
182
 
                .owner  = THIS_MODULE,
183
 
                .name   = "lm78",
184
 
        },
185
 
        .probe          = lm78_isa_probe,
186
 
        .remove         = __devexit_p(lm78_isa_remove),
187
 
};
188
 
 
189
 
 
190
150
/* 7 Voltages */
191
151
static ssize_t show_in(struct device *dev, struct device_attribute *da,
192
152
                       char *buf)
514
474
        .attrs = lm78_attributes,
515
475
};
516
476
 
 
477
/*
 
478
 * ISA related code
 
479
 */
 
480
#ifdef CONFIG_ISA
 
481
 
 
482
/* ISA device, if found */
 
483
static struct platform_device *pdev;
 
484
 
 
485
static unsigned short isa_address = 0x290;
 
486
 
517
487
/* I2C devices get this name attribute automatically, but for ISA devices
518
488
   we must create it by ourselves. */
519
489
static ssize_t show_name(struct device *dev, struct device_attribute
525
495
}
526
496
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
527
497
 
 
498
static struct lm78_data *lm78_data_if_isa(void)
 
499
{
 
500
        return pdev ? platform_get_drvdata(pdev) : NULL;
 
501
}
 
502
 
528
503
/* Returns 1 if the I2C chip appears to be an alias of the ISA chip */
529
504
static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
530
505
{
558
533
 
559
534
        return 1;
560
535
}
 
536
#else /* !CONFIG_ISA */
 
537
 
 
538
static int lm78_alias_detect(struct i2c_client *client, u8 chipid)
 
539
{
 
540
        return 0;
 
541
}
 
542
 
 
543
static struct lm78_data *lm78_data_if_isa(void)
 
544
{
 
545
        return NULL;
 
546
}
 
547
#endif /* CONFIG_ISA */
561
548
 
562
549
static int lm78_i2c_detect(struct i2c_client *client,
563
550
                           struct i2c_board_info *info)
564
551
{
565
552
        int i;
566
 
        struct lm78_data *isa = pdev ? platform_get_drvdata(pdev) : NULL;
 
553
        struct lm78_data *isa = lm78_data_if_isa();
567
554
        const char *client_name;
568
555
        struct i2c_adapter *adapter = client->adapter;
569
556
        int address = client->addr;
663
650
        return 0;
664
651
}
665
652
 
666
 
static int __devinit lm78_isa_probe(struct platform_device *pdev)
667
 
{
668
 
        int err;
669
 
        struct lm78_data *data;
670
 
        struct resource *res;
671
 
 
672
 
        /* Reserve the ISA region */
673
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
674
 
        if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) {
675
 
                err = -EBUSY;
676
 
                goto exit;
677
 
        }
678
 
 
679
 
        if (!(data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL))) {
680
 
                err = -ENOMEM;
681
 
                goto exit_release_region;
682
 
        }
683
 
        mutex_init(&data->lock);
684
 
        data->isa_addr = res->start;
685
 
        platform_set_drvdata(pdev, data);
686
 
 
687
 
        if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
688
 
                data->type = lm79;
689
 
                data->name = "lm79";
690
 
        } else {
691
 
                data->type = lm78;
692
 
                data->name = "lm78";
693
 
        }
694
 
 
695
 
        /* Initialize the LM78 chip */
696
 
        lm78_init_device(data);
697
 
 
698
 
        /* Register sysfs hooks */
699
 
        if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group))
700
 
         || (err = device_create_file(&pdev->dev, &dev_attr_name)))
701
 
                goto exit_remove_files;
702
 
 
703
 
        data->hwmon_dev = hwmon_device_register(&pdev->dev);
704
 
        if (IS_ERR(data->hwmon_dev)) {
705
 
                err = PTR_ERR(data->hwmon_dev);
706
 
                goto exit_remove_files;
707
 
        }
708
 
 
709
 
        return 0;
710
 
 
711
 
 exit_remove_files:
712
 
        sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
713
 
        device_remove_file(&pdev->dev, &dev_attr_name);
714
 
        kfree(data);
715
 
 exit_release_region:
716
 
        release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
717
 
 exit:
718
 
        return err;
719
 
}
720
 
 
721
 
static int __devexit lm78_isa_remove(struct platform_device *pdev)
722
 
{
723
 
        struct lm78_data *data = platform_get_drvdata(pdev);
724
 
        struct resource *res;
725
 
 
726
 
        hwmon_device_unregister(data->hwmon_dev);
727
 
        sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
728
 
        device_remove_file(&pdev->dev, &dev_attr_name);
729
 
        kfree(data);
730
 
 
731
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
732
 
        release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
733
 
 
734
 
        return 0;
735
 
}
 
653
static const struct i2c_device_id lm78_i2c_id[] = {
 
654
        { "lm78", lm78 },
 
655
        { "lm79", lm79 },
 
656
        { }
 
657
};
 
658
MODULE_DEVICE_TABLE(i2c, lm78_i2c_id);
 
659
 
 
660
static struct i2c_driver lm78_driver = {
 
661
        .class          = I2C_CLASS_HWMON,
 
662
        .driver = {
 
663
                .name   = "lm78",
 
664
        },
 
665
        .probe          = lm78_i2c_probe,
 
666
        .remove         = lm78_i2c_remove,
 
667
        .id_table       = lm78_i2c_id,
 
668
        .detect         = lm78_i2c_detect,
 
669
        .address_list   = normal_i2c,
 
670
};
736
671
 
737
672
/* The SMBus locks itself, but ISA access must be locked explicitly! 
738
673
   We don't want to lock the whole ISA bus, so we lock each client
743
678
{
744
679
        struct i2c_client *client = data->client;
745
680
 
 
681
#ifdef CONFIG_ISA
746
682
        if (!client) { /* ISA device */
747
683
                int res;
748
684
                mutex_lock(&data->lock);
751
687
                mutex_unlock(&data->lock);
752
688
                return res;
753
689
        } else
 
690
#endif
754
691
                return i2c_smbus_read_byte_data(client, reg);
755
692
}
756
693
 
765
702
{
766
703
        struct i2c_client *client = data->client;
767
704
 
 
705
#ifdef CONFIG_ISA
768
706
        if (!client) { /* ISA device */
769
707
                mutex_lock(&data->lock);
770
708
                outb_p(reg, data->isa_addr + LM78_ADDR_REG_OFFSET);
772
710
                mutex_unlock(&data->lock);
773
711
                return 0;
774
712
        } else
 
713
#endif
775
714
                return i2c_smbus_write_byte_data(client, reg, value);
776
715
}
777
716
 
849
788
        return data;
850
789
}
851
790
 
 
791
#ifdef CONFIG_ISA
 
792
static int __devinit lm78_isa_probe(struct platform_device *pdev)
 
793
{
 
794
        int err;
 
795
        struct lm78_data *data;
 
796
        struct resource *res;
 
797
 
 
798
        /* Reserve the ISA region */
 
799
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 
800
        if (!request_region(res->start + LM78_ADDR_REG_OFFSET, 2, "lm78")) {
 
801
                err = -EBUSY;
 
802
                goto exit;
 
803
        }
 
804
 
 
805
        data = kzalloc(sizeof(struct lm78_data), GFP_KERNEL);
 
806
        if (!data) {
 
807
                err = -ENOMEM;
 
808
                goto exit_release_region;
 
809
        }
 
810
        mutex_init(&data->lock);
 
811
        data->isa_addr = res->start;
 
812
        platform_set_drvdata(pdev, data);
 
813
 
 
814
        if (lm78_read_value(data, LM78_REG_CHIPID) & 0x80) {
 
815
                data->type = lm79;
 
816
                data->name = "lm79";
 
817
        } else {
 
818
                data->type = lm78;
 
819
                data->name = "lm78";
 
820
        }
 
821
 
 
822
        /* Initialize the LM78 chip */
 
823
        lm78_init_device(data);
 
824
 
 
825
        /* Register sysfs hooks */
 
826
        if ((err = sysfs_create_group(&pdev->dev.kobj, &lm78_group))
 
827
         || (err = device_create_file(&pdev->dev, &dev_attr_name)))
 
828
                goto exit_remove_files;
 
829
 
 
830
        data->hwmon_dev = hwmon_device_register(&pdev->dev);
 
831
        if (IS_ERR(data->hwmon_dev)) {
 
832
                err = PTR_ERR(data->hwmon_dev);
 
833
                goto exit_remove_files;
 
834
        }
 
835
 
 
836
        return 0;
 
837
 
 
838
 exit_remove_files:
 
839
        sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
 
840
        device_remove_file(&pdev->dev, &dev_attr_name);
 
841
        kfree(data);
 
842
 exit_release_region:
 
843
        release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
 
844
 exit:
 
845
        return err;
 
846
}
 
847
 
 
848
static int __devexit lm78_isa_remove(struct platform_device *pdev)
 
849
{
 
850
        struct lm78_data *data = platform_get_drvdata(pdev);
 
851
        struct resource *res;
 
852
 
 
853
        hwmon_device_unregister(data->hwmon_dev);
 
854
        sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
 
855
        device_remove_file(&pdev->dev, &dev_attr_name);
 
856
        kfree(data);
 
857
 
 
858
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 
859
        release_region(res->start + LM78_ADDR_REG_OFFSET, 2);
 
860
 
 
861
        return 0;
 
862
}
 
863
 
 
864
static struct platform_driver lm78_isa_driver = {
 
865
        .driver = {
 
866
                .owner  = THIS_MODULE,
 
867
                .name   = "lm78",
 
868
        },
 
869
        .probe          = lm78_isa_probe,
 
870
        .remove         = __devexit_p(lm78_isa_remove),
 
871
};
 
872
 
852
873
/* return 1 if a supported chip is found, 0 otherwise */
853
874
static int __init lm78_isa_found(unsigned short address)
854
875
{
969
990
        return err;
970
991
}
971
992
 
972
 
static int __init sm_lm78_init(void)
 
993
static int __init lm78_isa_register(void)
973
994
{
974
995
        int res;
975
996
 
976
 
        /* We register the ISA device first, so that we can skip the
977
 
         * registration of an I2C interface to the same device. */
978
997
        if (lm78_isa_found(isa_address)) {
979
998
                res = platform_driver_register(&lm78_isa_driver);
980
999
                if (res)
986
1005
                        goto exit_unreg_isa_driver;
987
1006
        }
988
1007
 
989
 
        res = i2c_add_driver(&lm78_driver);
990
 
        if (res)
991
 
                goto exit_unreg_isa_device;
992
 
 
993
1008
        return 0;
994
1009
 
995
 
 exit_unreg_isa_device:
996
 
        platform_device_unregister(pdev);
997
1010
 exit_unreg_isa_driver:
998
1011
        platform_driver_unregister(&lm78_isa_driver);
999
1012
 exit:
1000
1013
        return res;
1001
1014
}
1002
1015
 
1003
 
static void __exit sm_lm78_exit(void)
 
1016
static void lm78_isa_unregister(void)
1004
1017
{
1005
1018
        if (pdev) {
1006
1019
                platform_device_unregister(pdev);
1007
1020
                platform_driver_unregister(&lm78_isa_driver);
1008
1021
        }
 
1022
}
 
1023
#else /* !CONFIG_ISA */
 
1024
 
 
1025
static int __init lm78_isa_register(void)
 
1026
{
 
1027
        return 0;
 
1028
}
 
1029
 
 
1030
static void lm78_isa_unregister(void)
 
1031
{
 
1032
}
 
1033
#endif /* CONFIG_ISA */
 
1034
 
 
1035
static int __init sm_lm78_init(void)
 
1036
{
 
1037
        int res;
 
1038
 
 
1039
        /* We register the ISA device first, so that we can skip the
 
1040
         * registration of an I2C interface to the same device. */
 
1041
        res = lm78_isa_register();
 
1042
        if (res)
 
1043
                goto exit;
 
1044
 
 
1045
        res = i2c_add_driver(&lm78_driver);
 
1046
        if (res)
 
1047
                goto exit_unreg_isa_device;
 
1048
 
 
1049
        return 0;
 
1050
 
 
1051
 exit_unreg_isa_device:
 
1052
        lm78_isa_unregister();
 
1053
 exit:
 
1054
        return res;
 
1055
}
 
1056
 
 
1057
static void __exit sm_lm78_exit(void)
 
1058
{
 
1059
        lm78_isa_unregister();
1009
1060
        i2c_del_driver(&lm78_driver);
1010
1061
}
1011
1062
 
1012
 
 
1013
 
 
1014
 
MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
 
1063
MODULE_AUTHOR("Frodo Looijaard, Jean Delvare <khali@linux-fr.org>");
1015
1064
MODULE_DESCRIPTION("LM78/LM79 driver");
1016
1065
MODULE_LICENSE("GPL");
1017
1066