aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/char/hpet.c65
1 files changed, 35 insertions, 30 deletions
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 86a2ee40078b..3808d9572619 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -284,7 +284,8 @@ static int hpet_mmap(struct file *file, struct vm_area_struct *vma)
284 284
285 if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT, 285 if (io_remap_pfn_range(vma, vma->vm_start, addr >> PAGE_SHIFT,
286 PAGE_SIZE, vma->vm_page_prot)) { 286 PAGE_SIZE, vma->vm_page_prot)) {
287 printk(KERN_ERR "remap_pfn_range failed in hpet.c\n"); 287 printk(KERN_ERR "%s: io_remap_pfn_range failed\n",
288 __FUNCTION__);
288 return -EAGAIN; 289 return -EAGAIN;
289 } 290 }
290 291
@@ -565,6 +566,17 @@ static struct file_operations hpet_fops = {
565 .mmap = hpet_mmap, 566 .mmap = hpet_mmap,
566}; 567};
567 568
569static int hpet_is_known(struct hpet_data *hdp)
570{
571 struct hpets *hpetp;
572
573 for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next)
574 if (hpetp->hp_hpet_phys == hdp->hd_phys_address)
575 return 1;
576
577 return 0;
578}
579
568EXPORT_SYMBOL(hpet_alloc); 580EXPORT_SYMBOL(hpet_alloc);
569EXPORT_SYMBOL(hpet_register); 581EXPORT_SYMBOL(hpet_register);
570EXPORT_SYMBOL(hpet_unregister); 582EXPORT_SYMBOL(hpet_unregister);
@@ -730,11 +742,10 @@ static void hpet_register_interpolator(struct hpets *hpetp)
730#ifdef CONFIG_TIME_INTERPOLATION 742#ifdef CONFIG_TIME_INTERPOLATION
731 struct time_interpolator *ti; 743 struct time_interpolator *ti;
732 744
733 ti = kmalloc(sizeof(*ti), GFP_KERNEL); 745 ti = kzalloc(sizeof(*ti), GFP_KERNEL);
734 if (!ti) 746 if (!ti)
735 return; 747 return;
736 748
737 memset(ti, 0, sizeof(*ti));
738 ti->source = TIME_SOURCE_MMIO64; 749 ti->source = TIME_SOURCE_MMIO64;
739 ti->shift = 10; 750 ti->shift = 10;
740 ti->addr = &hpetp->hp_hpet->hpet_mc; 751 ti->addr = &hpetp->hp_hpet->hpet_mc;
@@ -799,32 +810,29 @@ int hpet_alloc(struct hpet_data *hdp)
799 struct hpets *hpetp; 810 struct hpets *hpetp;
800 size_t siz; 811 size_t siz;
801 struct hpet __iomem *hpet; 812 struct hpet __iomem *hpet;
802 static struct hpets *last = (struct hpets *)0; 813 static struct hpets *last = NULL;
803 unsigned long period; 814 unsigned long period;
804 unsigned long long temp; 815 unsigned long long temp;
805 816
806 /* 817 /*
807 * hpet_alloc can be called by platform dependent code. 818 * hpet_alloc can be called by platform dependent code.
808 * if platform dependent code has allocated the hpet 819 * If platform dependent code has allocated the hpet that
809 * ACPI also reports hpet, then we catch it here. 820 * ACPI has also reported, then we catch it here.
810 */ 821 */
811 for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) 822 if (hpet_is_known(hdp)) {
812 if (hpetp->hp_hpet_phys == hdp->hd_phys_address) { 823 printk(KERN_DEBUG "%s: duplicate HPET ignored\n",
813 printk(KERN_DEBUG "%s: duplicate HPET ignored\n", 824 __FUNCTION__);
814 __FUNCTION__); 825 return 0;
815 return 0; 826 }
816 }
817 827
818 siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) * 828 siz = sizeof(struct hpets) + ((hdp->hd_nirqs - 1) *
819 sizeof(struct hpet_dev)); 829 sizeof(struct hpet_dev));
820 830
821 hpetp = kmalloc(siz, GFP_KERNEL); 831 hpetp = kzalloc(siz, GFP_KERNEL);
822 832
823 if (!hpetp) 833 if (!hpetp)
824 return -ENOMEM; 834 return -ENOMEM;
825 835
826 memset(hpetp, 0, siz);
827
828 hpetp->hp_which = hpet_nhpet++; 836 hpetp->hp_which = hpet_nhpet++;
829 hpetp->hp_hpet = hdp->hd_address; 837 hpetp->hp_hpet = hdp->hd_address;
830 hpetp->hp_hpet_phys = hdp->hd_phys_address; 838 hpetp->hp_hpet_phys = hdp->hd_phys_address;
@@ -911,7 +919,6 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
911 struct hpet_data *hdp; 919 struct hpet_data *hdp;
912 acpi_status status; 920 acpi_status status;
913 struct acpi_resource_address64 addr; 921 struct acpi_resource_address64 addr;
914 struct hpets *hpetp;
915 922
916 hdp = data; 923 hdp = data;
917 924
@@ -924,13 +931,12 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
924 hdp->hd_phys_address = addr.min_address_range; 931 hdp->hd_phys_address = addr.min_address_range;
925 hdp->hd_address = ioremap(addr.min_address_range, size); 932 hdp->hd_address = ioremap(addr.min_address_range, size);
926 933
927 for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) 934 if (hpet_is_known(hdp)) {
928 if (hpetp->hp_hpet_phys == hdp->hd_phys_address) { 935 printk(KERN_DEBUG "%s: 0x%lx is busy\n",
929 printk(KERN_DEBUG "%s: 0x%lx is busy\n", 936 __FUNCTION__, hdp->hd_phys_address);
930 __FUNCTION__, hdp->hd_phys_address); 937 iounmap(hdp->hd_address);
931 iounmap(hdp->hd_address); 938 return -EBUSY;
932 return -EBUSY; 939 }
933 }
934 } else if (res->id == ACPI_RSTYPE_FIXED_MEM32) { 940 } else if (res->id == ACPI_RSTYPE_FIXED_MEM32) {
935 struct acpi_resource_fixed_mem32 *fixmem32; 941 struct acpi_resource_fixed_mem32 *fixmem32;
936 942
@@ -942,13 +948,12 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data)
942 hdp->hd_address = ioremap(fixmem32->range_base_address, 948 hdp->hd_address = ioremap(fixmem32->range_base_address,
943 HPET_RANGE_SIZE); 949 HPET_RANGE_SIZE);
944 950
945 for (hpetp = hpets; hpetp; hpetp = hpetp->hp_next) 951 if (hpet_is_known(hdp)) {
946 if (hpetp->hp_hpet_phys == hdp->hd_phys_address) { 952 printk(KERN_DEBUG "%s: 0x%lx is busy\n",
947 printk(KERN_DEBUG "%s: 0x%lx is busy\n", 953 __FUNCTION__, hdp->hd_phys_address);
948 __FUNCTION__, hdp->hd_phys_address); 954 iounmap(hdp->hd_address);
949 iounmap(hdp->hd_address); 955 return -EBUSY;
950 return -EBUSY; 956 }
951 }
952 } else if (res->id == ACPI_RSTYPE_EXT_IRQ) { 957 } else if (res->id == ACPI_RSTYPE_EXT_IRQ) {
953 struct acpi_resource_ext_irq *irqp; 958 struct acpi_resource_ext_irq *irqp;
954 int i; 959 int i;