diff options
-rw-r--r-- | drivers/char/hpet.c | 65 |
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 | ||
569 | static 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 | |||
568 | EXPORT_SYMBOL(hpet_alloc); | 580 | EXPORT_SYMBOL(hpet_alloc); |
569 | EXPORT_SYMBOL(hpet_register); | 581 | EXPORT_SYMBOL(hpet_register); |
570 | EXPORT_SYMBOL(hpet_unregister); | 582 | EXPORT_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; |