diff options
Diffstat (limited to 'drivers/char')
59 files changed, 638 insertions, 461 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig index ea6f6325f9ba..72bedad6bf8c 100644 --- a/drivers/char/Kconfig +++ b/drivers/char/Kconfig @@ -418,8 +418,8 @@ config APPLICOM If unsure, say N. config SONYPI - tristate "Sony Vaio Programmable I/O Control Device support (EXPERIMENTAL)" - depends on EXPERIMENTAL && X86 && PCI && INPUT && !64BIT + tristate "Sony Vaio Programmable I/O Control Device support" + depends on X86 && PCI && INPUT && !64BIT ---help--- This driver enables access to the Sony Programmable I/O Control Device which can be found in many (all ?) Sony Vaio laptops. @@ -566,7 +566,7 @@ source "drivers/char/tpm/Kconfig" config TELCLOCK tristate "Telecom clock driver for ATCA SBC" - depends on EXPERIMENTAL && X86 + depends on X86 default n help The telecom clock device is specific to the MPCBL0010 and MPCBL0050 diff --git a/drivers/char/Makefile b/drivers/char/Makefile index d0b27a39f1d4..7ff1d0d208a7 100644 --- a/drivers/char/Makefile +++ b/drivers/char/Makefile @@ -52,7 +52,6 @@ obj-$(CONFIG_TELCLOCK) += tlclk.o obj-$(CONFIG_MWAVE) += mwave/ obj-$(CONFIG_AGP) += agp/ obj-$(CONFIG_PCMCIA) += pcmcia/ -obj-$(CONFIG_IPMI_HANDLER) += ipmi/ obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o obj-$(CONFIG_TCG_TPM) += tpm/ diff --git a/drivers/char/agp/ali-agp.c b/drivers/char/agp/ali-agp.c index fd793519ea2b..478493543b32 100644 --- a/drivers/char/agp/ali-agp.c +++ b/drivers/char/agp/ali-agp.c @@ -249,7 +249,7 @@ static const struct agp_bridge_driver ali_m1541_bridge = { }; -static struct agp_device_ids ali_agp_device_ids[] __devinitdata = +static struct agp_device_ids ali_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_AL_M1541, @@ -374,7 +374,7 @@ found: return agp_add_bridge(bridge); } -static void __devexit agp_ali_remove(struct pci_dev *pdev) +static void agp_ali_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c index f7e88787af97..1b2101160e98 100644 --- a/drivers/char/agp/amd-k7-agp.c +++ b/drivers/char/agp/amd-k7-agp.c @@ -388,7 +388,7 @@ static const struct agp_bridge_driver amd_irongate_driver = { .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; -static struct agp_device_ids amd_agp_device_ids[] __devinitdata = +static struct agp_device_ids amd_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006, @@ -480,7 +480,7 @@ static int __devinit agp_amdk7_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_amdk7_remove(struct pci_dev *pdev) +static void agp_amdk7_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c index 444f8b6ab411..061d46209b1a 100644 --- a/drivers/char/agp/amd64-agp.c +++ b/drivers/char/agp/amd64-agp.c @@ -579,7 +579,7 @@ static int __devinit agp_amd64_probe(struct pci_dev *pdev, return 0; } -static void __devexit agp_amd64_remove(struct pci_dev *pdev) +static void agp_amd64_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c index dc30e2243494..ed0433576e74 100644 --- a/drivers/char/agp/ati-agp.c +++ b/drivers/char/agp/ati-agp.c @@ -445,7 +445,7 @@ static const struct agp_bridge_driver ati_generic_bridge = { }; -static struct agp_device_ids ati_agp_device_ids[] __devinitdata = +static struct agp_device_ids ati_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_ATI_RS100, @@ -533,7 +533,7 @@ found: return agp_add_bridge(bridge); } -static void __devexit agp_ati_remove(struct pci_dev *pdev) +static void agp_ati_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c index d607f53d8afc..55f3e33a309f 100644 --- a/drivers/char/agp/efficeon-agp.c +++ b/drivers/char/agp/efficeon-agp.c @@ -407,7 +407,7 @@ static int __devinit agp_efficeon_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_efficeon_remove(struct pci_dev *pdev) +static void agp_efficeon_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c index 75b763cb3ea1..d328b662e50d 100644 --- a/drivers/char/agp/i460-agp.c +++ b/drivers/char/agp/i460-agp.c @@ -611,7 +611,7 @@ static int __devinit agp_intel_i460_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_intel_i460_remove(struct pci_dev *pdev) +static void agp_intel_i460_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c index b130df0a1958..f3a8f52b5a00 100644 --- a/drivers/char/agp/intel-agp.c +++ b/drivers/char/agp/intel-agp.c @@ -819,7 +819,7 @@ found_gmch: return err; } -static void __devexit agp_intel_remove(struct pci_dev *pdev) +static void agp_intel_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 58e32f7c3229..38390f7c6ab6 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c @@ -84,40 +84,33 @@ static struct _intel_private { #define IS_IRONLAKE intel_private.driver->is_ironlake #define HAS_PGTBL_EN intel_private.driver->has_pgtbl_enable -int intel_gtt_map_memory(struct page **pages, unsigned int num_entries, - struct scatterlist **sg_list, int *num_sg) +static int intel_gtt_map_memory(struct page **pages, + unsigned int num_entries, + struct sg_table *st) { - struct sg_table st; struct scatterlist *sg; int i; - if (*sg_list) - return 0; /* already mapped (for e.g. resume */ - DBG("try mapping %lu pages\n", (unsigned long)num_entries); - if (sg_alloc_table(&st, num_entries, GFP_KERNEL)) + if (sg_alloc_table(st, num_entries, GFP_KERNEL)) goto err; - *sg_list = sg = st.sgl; - - for (i = 0 ; i < num_entries; i++, sg = sg_next(sg)) + for_each_sg(st->sgl, sg, num_entries, i) sg_set_page(sg, pages[i], PAGE_SIZE, 0); - *num_sg = pci_map_sg(intel_private.pcidev, *sg_list, - num_entries, PCI_DMA_BIDIRECTIONAL); - if (unlikely(!*num_sg)) + if (!pci_map_sg(intel_private.pcidev, + st->sgl, st->nents, PCI_DMA_BIDIRECTIONAL)) goto err; return 0; err: - sg_free_table(&st); + sg_free_table(st); return -ENOMEM; } -EXPORT_SYMBOL(intel_gtt_map_memory); -void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg) +static void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg) { struct sg_table st; DBG("try unmapping %lu pages\n", (unsigned long)mem->page_count); @@ -130,7 +123,6 @@ void intel_gtt_unmap_memory(struct scatterlist *sg_list, int num_sg) sg_free_table(&st); } -EXPORT_SYMBOL(intel_gtt_unmap_memory); static void intel_fake_agp_enable(struct agp_bridge_data *bridge, u32 mode) { @@ -674,9 +666,14 @@ static int intel_gtt_init(void) gtt_map_size = intel_private.base.gtt_total_entries * 4; - intel_private.gtt = ioremap(intel_private.gtt_bus_addr, - gtt_map_size); - if (!intel_private.gtt) { + intel_private.gtt = NULL; + if (INTEL_GTT_GEN < 6 && INTEL_GTT_GEN > 2) + intel_private.gtt = ioremap_wc(intel_private.gtt_bus_addr, + gtt_map_size); + if (intel_private.gtt == NULL) + intel_private.gtt = ioremap(intel_private.gtt_bus_addr, + gtt_map_size); + if (intel_private.gtt == NULL) { intel_private.driver->cleanup(); iounmap(intel_private.registers); return -ENOMEM; @@ -879,8 +876,7 @@ static bool i830_check_flags(unsigned int flags) return false; } -void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, - unsigned int sg_len, +void intel_gtt_insert_sg_entries(struct sg_table *st, unsigned int pg_start, unsigned int flags) { @@ -892,12 +888,11 @@ void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, /* sg may merge pages, but we have to separate * per-page addr for GTT */ - for_each_sg(sg_list, sg, sg_len, i) { + for_each_sg(st->sgl, sg, st->nents, i) { len = sg_dma_len(sg) >> PAGE_SHIFT; for (m = 0; m < len; m++) { dma_addr_t addr = sg_dma_address(sg) + (m << PAGE_SHIFT); - intel_private.driver->write_entry(addr, - j, flags); + intel_private.driver->write_entry(addr, j, flags); j++; } } @@ -905,8 +900,10 @@ void intel_gtt_insert_sg_entries(struct scatterlist *sg_list, } EXPORT_SYMBOL(intel_gtt_insert_sg_entries); -void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, - struct page **pages, unsigned int flags) +static void intel_gtt_insert_pages(unsigned int first_entry, + unsigned int num_entries, + struct page **pages, + unsigned int flags) { int i, j; @@ -917,7 +914,6 @@ void intel_gtt_insert_pages(unsigned int first_entry, unsigned int num_entries, } readl(intel_private.gtt+j-1); } -EXPORT_SYMBOL(intel_gtt_insert_pages); static int intel_fake_agp_insert_entries(struct agp_memory *mem, off_t pg_start, int type) @@ -953,13 +949,15 @@ static int intel_fake_agp_insert_entries(struct agp_memory *mem, global_cache_flush(); if (intel_private.base.needs_dmar) { - ret = intel_gtt_map_memory(mem->pages, mem->page_count, - &mem->sg_list, &mem->num_sg); + struct sg_table st; + + ret = intel_gtt_map_memory(mem->pages, mem->page_count, &st); if (ret != 0) return ret; - intel_gtt_insert_sg_entries(mem->sg_list, mem->num_sg, - pg_start, type); + intel_gtt_insert_sg_entries(&st, pg_start, type); + mem->sg_list = st.sgl; + mem->num_sg = st.nents; } else intel_gtt_insert_pages(pg_start, mem->page_count, mem->pages, type); diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c index b9734a978186..66e0868000f4 100644 --- a/drivers/char/agp/nvidia-agp.c +++ b/drivers/char/agp/nvidia-agp.c @@ -388,7 +388,7 @@ static int __devinit agp_nvidia_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_nvidia_remove(struct pci_dev *pdev) +static void agp_nvidia_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c index 192000377737..a18791d7718a 100644 --- a/drivers/char/agp/sgi-agp.c +++ b/drivers/char/agp/sgi-agp.c @@ -289,12 +289,11 @@ static int __devinit agp_sgi_init(void) j = 0; list_for_each_entry(info, &tioca_list, ca_list) { - struct list_head *tmp; if (list_empty(info->ca_devices)) continue; - list_for_each(tmp, info->ca_devices) { + list_for_each_entry(pdev, info->ca_devices, bus_list) { u8 cap_ptr; - pdev = pci_dev_b(tmp); + if (pdev->class != (PCI_CLASS_DISPLAY_VGA << 8)) continue; cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP); @@ -328,7 +327,7 @@ static int __devinit agp_sgi_init(void) return 0; } -static void __devexit agp_sgi_cleanup(void) +static void agp_sgi_cleanup(void) { kfree(sgi_tioca_agp_bridges); sgi_tioca_agp_bridges = NULL; diff --git a/drivers/char/agp/sis-agp.c b/drivers/char/agp/sis-agp.c index 08704ae53956..93d1d31f9d0c 100644 --- a/drivers/char/agp/sis-agp.c +++ b/drivers/char/agp/sis-agp.c @@ -17,8 +17,8 @@ #define PCI_DEVICE_ID_SI_662 0x0662 #define PCI_DEVICE_ID_SI_671 0x0671 -static bool __devinitdata agp_sis_force_delay = 0; -static int __devinitdata agp_sis_agp_spec = -1; +static bool agp_sis_force_delay = 0; +static int agp_sis_agp_spec = -1; static int sis_fetch_size(void) { @@ -148,7 +148,7 @@ static struct agp_bridge_driver sis_driver = { }; // chipsets that require the 'delay hack' -static int sis_broken_chipsets[] __devinitdata = { +static int sis_broken_chipsets[] = { PCI_DEVICE_ID_SI_648, PCI_DEVICE_ID_SI_746, 0 // terminator @@ -211,7 +211,7 @@ static int __devinit agp_sis_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_sis_remove(struct pci_dev *pdev) +static void agp_sis_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c index f02f9b07fd4c..26020fb8d7a9 100644 --- a/drivers/char/agp/sworks-agp.c +++ b/drivers/char/agp/sworks-agp.c @@ -518,7 +518,7 @@ static int __devinit agp_serverworks_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_serverworks_remove(struct pci_dev *pdev) +static void agp_serverworks_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c index a32c492baf5c..011967ad3eed 100644 --- a/drivers/char/agp/uninorth-agp.c +++ b/drivers/char/agp/uninorth-agp.c @@ -557,7 +557,7 @@ const struct agp_bridge_driver u3_agp_driver = { .needs_scratch_page = true, }; -static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = { +static struct agp_device_ids uninorth_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP, .chipset_name = "UniNorth", @@ -663,7 +663,7 @@ static int __devinit agp_uninorth_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_uninorth_remove(struct pci_dev *pdev) +static void agp_uninorth_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c index 8bc384937401..6818595bb863 100644 --- a/drivers/char/agp/via-agp.c +++ b/drivers/char/agp/via-agp.c @@ -224,7 +224,7 @@ static const struct agp_bridge_driver via_driver = { .agp_type_to_mask_type = agp_generic_type_to_mask_type, }; -static struct agp_device_ids via_agp_device_ids[] __devinitdata = +static struct agp_device_ids via_agp_device_ids[] = { { .device_id = PCI_DEVICE_ID_VIA_82C597_0, @@ -485,7 +485,7 @@ static int __devinit agp_via_probe(struct pci_dev *pdev, return agp_add_bridge(bridge); } -static void __devexit agp_via_remove(struct pci_dev *pdev) +static void agp_via_remove(struct pci_dev *pdev) { struct agp_bridge_data *bridge = pci_get_drvdata(pdev); diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c index aab9605f0b43..24ffd8cec51e 100644 --- a/drivers/char/ds1620.c +++ b/drivers/char/ds1620.c @@ -74,21 +74,21 @@ static inline void netwinder_ds1620_reset(void) static inline void netwinder_lock(unsigned long *flags) { - spin_lock_irqsave(&nw_gpio_lock, *flags); + raw_spin_lock_irqsave(&nw_gpio_lock, *flags); } static inline void netwinder_unlock(unsigned long *flags) { - spin_unlock_irqrestore(&nw_gpio_lock, *flags); + raw_spin_unlock_irqrestore(&nw_gpio_lock, *flags); } static inline void netwinder_set_fan(int i) { unsigned long flags; - spin_lock_irqsave(&nw_gpio_lock, flags); + raw_spin_lock_irqsave(&nw_gpio_lock, flags); nw_gpio_modify_op(GPIO_FAN, i ? GPIO_FAN : 0); - spin_unlock_irqrestore(&nw_gpio_lock, flags); + raw_spin_unlock_irqrestore(&nw_gpio_lock, flags); } static inline int netwinder_get_fan(void) diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index dfd7876f127c..fe6d4be48296 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c @@ -816,7 +816,7 @@ static unsigned long __hpet_calibrate(struct hpets *hpetp) static unsigned long hpet_calibrate(struct hpets *hpetp) { - unsigned long ret = -1; + unsigned long ret = ~0UL; unsigned long tmp; /* @@ -1001,6 +1001,9 @@ static acpi_status hpet_resources(struct acpi_resource *res, void *data) irqp = &res->data.extended_irq; for (i = 0; i < irqp->interrupt_count; i++) { + if (hdp->hd_nirqs >= HPET_MAX_TIMERS) + break; + irq = acpi_register_gsi(NULL, irqp->interrupts[i], irqp->triggering, irqp->polarity); if (irq < 0) diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index fbd9b2b850ef..c5a0262251bc 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -127,12 +127,12 @@ config HW_RANDOM_VIA If unsure, say Y. config HW_RANDOM_IXP4XX - tristate "Intel IXP4xx NPU HW Random Number Generator support" + tristate "Intel IXP4xx NPU HW Pseudo-Random Number Generator support" depends on HW_RANDOM && ARCH_IXP4XX default HW_RANDOM ---help--- - This driver provides kernel-side support for the Random - Number Generator hardware found on the Intel IXP4xx NPU. + This driver provides kernel-side support for the Pseudo-Random + Number Generator hardware found on the Intel IXP45x/46x NPU. To compile this driver as a module, choose M here: the module will be called ixp4xx-rng. @@ -216,7 +216,7 @@ config HW_RANDOM_MXC_RNGA config HW_RANDOM_NOMADIK tristate "ST-Ericsson Nomadik Random Number Generator support" - depends on HW_RANDOM && PLAT_NOMADIK + depends on HW_RANDOM && ARCH_NOMADIK ---help--- This driver provides kernel-side support for the Random Number Generator hardware found on ST-Ericsson SoCs (8815 and 8500). diff --git a/drivers/char/hw_random/atmel-rng.c b/drivers/char/hw_random/atmel-rng.c index 731c9046cf7b..5a4a6e70478b 100644 --- a/drivers/char/hw_random/atmel-rng.c +++ b/drivers/char/hw_random/atmel-rng.c @@ -98,7 +98,7 @@ err_enable: return ret; } -static int __devexit atmel_trng_remove(struct platform_device *pdev) +static int atmel_trng_remove(struct platform_device *pdev) { struct atmel_trng *trng = platform_get_drvdata(pdev); diff --git a/drivers/char/hw_random/bcm63xx-rng.c b/drivers/char/hw_random/bcm63xx-rng.c index aec6a4277caa..ae95bcb18d4a 100644 --- a/drivers/char/hw_random/bcm63xx-rng.c +++ b/drivers/char/hw_random/bcm63xx-rng.c @@ -145,7 +145,7 @@ out: return ret; } -static int __devexit bcm63xx_rng_remove(struct platform_device *pdev) +static int bcm63xx_rng_remove(struct platform_device *pdev) { struct hwrng *rng = platform_get_drvdata(pdev); struct bcm63xx_rng_priv *priv = to_rng_priv(rng); diff --git a/drivers/char/hw_random/exynos-rng.c b/drivers/char/hw_random/exynos-rng.c index 232ba9ce579c..bdc852ea7632 100644 --- a/drivers/char/hw_random/exynos-rng.c +++ b/drivers/char/hw_random/exynos-rng.c @@ -134,7 +134,7 @@ static int __devinit exynos_rng_probe(struct platform_device *pdev) return hwrng_register(&exynos_rng->rng); } -static int __devexit exynos_rng_remove(struct platform_device *pdev) +static int exynos_rng_remove(struct platform_device *pdev) { struct exynos_rng *exynos_rng = platform_get_drvdata(pdev); diff --git a/drivers/char/hw_random/ixp4xx-rng.c b/drivers/char/hw_random/ixp4xx-rng.c index 263567f5f392..beec1627db3c 100644 --- a/drivers/char/hw_random/ixp4xx-rng.c +++ b/drivers/char/hw_random/ixp4xx-rng.c @@ -45,6 +45,9 @@ static int __init ixp4xx_rng_init(void) void __iomem * rng_base; int err; + if (!cpu_is_ixp46x()) /* includes IXP455 */ + return -ENOSYS; + rng_base = ioremap(0x70002100, 4); if (!rng_base) return -ENOMEM; @@ -68,5 +71,5 @@ module_init(ixp4xx_rng_init); module_exit(ixp4xx_rng_exit); MODULE_AUTHOR("Deepak Saxena <dsaxena@plexity.net>"); -MODULE_DESCRIPTION("H/W Random Number Generator (RNG) driver for IXP4xx"); +MODULE_DESCRIPTION("H/W Pseudo-Random Number Generator (RNG) driver for IXP45x/46x"); MODULE_LICENSE("GPL"); diff --git a/drivers/char/hw_random/mxc-rnga.c b/drivers/char/hw_random/mxc-rnga.c index 85074de5042e..f05d85713fd3 100644 --- a/drivers/char/hw_random/mxc-rnga.c +++ b/drivers/char/hw_random/mxc-rnga.c @@ -59,16 +59,21 @@ #define RNGA_STATUS_LAST_READ_STATUS 0x00000002 #define RNGA_STATUS_SECURITY_VIOLATION 0x00000001 -static struct platform_device *rng_dev; +struct mxc_rng { + struct device *dev; + struct hwrng rng; + void __iomem *mem; + struct clk *clk; +}; static int mxc_rnga_data_present(struct hwrng *rng, int wait) { - void __iomem *rng_base = (void __iomem *)rng->priv; int i; + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); for (i = 0; i < 20; i++) { /* how many random numbers are in FIFO? [0-16] */ - int level = (__raw_readl(rng_base + RNGA_STATUS) & + int level = (__raw_readl(mxc_rng->mem + RNGA_STATUS) & RNGA_STATUS_LEVEL_MASK) >> 8; if (level || !wait) return !!level; @@ -81,20 +86,20 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) { int err; u32 ctrl; - void __iomem *rng_base = (void __iomem *)rng->priv; + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); /* retrieve a random number from FIFO */ - *data = __raw_readl(rng_base + RNGA_OUTPUT_FIFO); + *data = __raw_readl(mxc_rng->mem + RNGA_OUTPUT_FIFO); /* some error while reading this random number? */ - err = __raw_readl(rng_base + RNGA_STATUS) & RNGA_STATUS_ERROR_INT; + err = __raw_readl(mxc_rng->mem + RNGA_STATUS) & RNGA_STATUS_ERROR_INT; /* if error: clear error interrupt, but doesn't return random number */ if (err) { - dev_dbg(&rng_dev->dev, "Error while reading random number!\n"); - ctrl = __raw_readl(rng_base + RNGA_CONTROL); + dev_dbg(mxc_rng->dev, "Error while reading random number!\n"); + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); __raw_writel(ctrl | RNGA_CONTROL_CLEAR_INT, - rng_base + RNGA_CONTROL); + mxc_rng->mem + RNGA_CONTROL); return 0; } else return 4; @@ -103,22 +108,22 @@ static int mxc_rnga_data_read(struct hwrng *rng, u32 * data) static int mxc_rnga_init(struct hwrng *rng) { u32 ctrl, osc; - void __iomem *rng_base = (void __iomem *)rng->priv; + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); /* wake up */ - ctrl = __raw_readl(rng_base + RNGA_CONTROL); - __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, rng_base + RNGA_CONTROL); + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); + __raw_writel(ctrl & ~RNGA_CONTROL_SLEEP, mxc_rng->mem + RNGA_CONTROL); /* verify if oscillator is working */ - osc = __raw_readl(rng_base + RNGA_STATUS); + osc = __raw_readl(mxc_rng->mem + RNGA_STATUS); if (osc & RNGA_STATUS_OSC_DEAD) { - dev_err(&rng_dev->dev, "RNGA Oscillator is dead!\n"); + dev_err(mxc_rng->dev, "RNGA Oscillator is dead!\n"); return -ENODEV; } /* go running */ - ctrl = __raw_readl(rng_base + RNGA_CONTROL); - __raw_writel(ctrl | RNGA_CONTROL_GO, rng_base + RNGA_CONTROL); + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); + __raw_writel(ctrl | RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL); return 0; } @@ -126,40 +131,40 @@ static int mxc_rnga_init(struct hwrng *rng) static void mxc_rnga_cleanup(struct hwrng *rng) { u32 ctrl; - void __iomem *rng_base = (void __iomem *)rng->priv; + struct mxc_rng *mxc_rng = container_of(rng, struct mxc_rng, rng); - ctrl = __raw_readl(rng_base + RNGA_CONTROL); + ctrl = __raw_readl(mxc_rng->mem + RNGA_CONTROL); /* stop rnga */ - __raw_writel(ctrl & ~RNGA_CONTROL_GO, rng_base + RNGA_CONTROL); + __raw_writel(ctrl & ~RNGA_CONTROL_GO, mxc_rng->mem + RNGA_CONTROL); } -static struct hwrng mxc_rnga = { - .name = "mxc-rnga", - .init = mxc_rnga_init, - .cleanup = mxc_rnga_cleanup, - .data_present = mxc_rnga_data_present, - .data_read = mxc_rnga_data_read -}; - static int __init mxc_rnga_probe(struct platform_device *pdev) { int err = -ENODEV; - struct clk *clk; struct resource *res, *mem; - void __iomem *rng_base = NULL; - - if (rng_dev) - return -EBUSY; - - clk = clk_get(&pdev->dev, "rng"); - if (IS_ERR(clk)) { + struct mxc_rng *mxc_rng; + + mxc_rng = devm_kzalloc(&pdev->dev, sizeof(struct mxc_rng), + GFP_KERNEL); + if (!mxc_rng) + return -ENOMEM; + + mxc_rng->dev = &pdev->dev; + mxc_rng->rng.name = "mxc-rnga"; + mxc_rng->rng.init = mxc_rnga_init; + mxc_rng->rng.cleanup = mxc_rnga_cleanup, + mxc_rng->rng.data_present = mxc_rnga_data_present, + mxc_rng->rng.data_read = mxc_rnga_data_read, + + mxc_rng->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(mxc_rng->clk)) { dev_err(&pdev->dev, "Could not get rng_clk!\n"); - err = PTR_ERR(clk); + err = PTR_ERR(mxc_rng->clk); goto out; } - clk_enable(clk); + clk_prepare_enable(mxc_rng->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { @@ -173,36 +178,27 @@ static int __init mxc_rnga_probe(struct platform_device *pdev) goto err_region; } - rng_base = ioremap(res->start, resource_size(res)); - if (!rng_base) { + mxc_rng->mem = ioremap(res->start, resource_size(res)); + if (!mxc_rng->mem) { err = -ENOMEM; goto err_ioremap; } - mxc_rnga.priv = (unsigned long)rng_base; - - err = hwrng_register(&mxc_rnga); + err = hwrng_register(&mxc_rng->rng); if (err) { dev_err(&pdev->dev, "MXC RNGA registering failed (%d)\n", err); - goto err_register; + goto err_ioremap; } - rng_dev = pdev; - dev_info(&pdev->dev, "MXC RNGA Registered.\n"); return 0; -err_register: - iounmap(rng_base); - rng_base = NULL; - err_ioremap: release_mem_region(res->start, resource_size(res)); err_region: - clk_disable(clk); - clk_put(clk); + clk_disable_unprepare(mxc_rng->clk); out: return err; @@ -211,17 +207,15 @@ out: static int __exit mxc_rnga_remove(struct platform_device *pdev) { struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - void __iomem *rng_base = (void __iomem *)mxc_rnga.priv; - struct clk *clk = clk_get(&pdev->dev, "rng"); + struct mxc_rng *mxc_rng = platform_get_drvdata(pdev); - hwrng_unregister(&mxc_rnga); + hwrng_unregister(&mxc_rng->rng); - iounmap(rng_base); + iounmap(mxc_rng->mem); release_mem_region(res->start, resource_size(res)); - clk_disable(clk); - clk_put(clk); + clk_disable_unprepare(mxc_rng->clk); return 0; } diff --git a/drivers/char/hw_random/n2-drv.c b/drivers/char/hw_random/n2-drv.c index ebd48f0135da..d68a72a08b51 100644 --- a/drivers/char/hw_random/n2-drv.c +++ b/drivers/char/hw_random/n2-drv.c @@ -25,7 +25,7 @@ #define DRV_MODULE_VERSION "0.2" #define DRV_MODULE_RELDATE "July 27, 2011" -static char version[] __devinitdata = +static char version[] = DRV_MODULE_NAME ".c:v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n"; MODULE_AUTHOR("David S. Miller (davem@davemloft.net)"); @@ -719,7 +719,7 @@ out: return err; } -static int __devexit n2rng_remove(struct platform_device *op) +static int n2rng_remove(struct platform_device *op) { struct n2rng *np = dev_get_drvdata(&op->dev); diff --git a/drivers/char/hw_random/octeon-rng.c b/drivers/char/hw_random/octeon-rng.c index 0943edc782a1..5c34c092af71 100644 --- a/drivers/char/hw_random/octeon-rng.c +++ b/drivers/char/hw_random/octeon-rng.c @@ -75,42 +75,35 @@ static int __devinit octeon_rng_probe(struct platform_device *pdev) res_ports = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res_ports) - goto err_ports; + return -ENOENT; res_result = platform_get_resource(pdev, IORESOURCE_MEM, 1); if (!res_result) - goto err_ports; + return -ENOENT; rng->control_status = devm_ioremap_nocache(&pdev->dev, res_ports->start, sizeof(u64)); if (!rng->control_status) - goto err_ports; + return -ENOENT; rng->result = devm_ioremap_nocache(&pdev->dev, res_result->start, sizeof(u64)); if (!rng->result) - goto err_r; + return -ENOENT; rng->ops = ops; dev_set_drvdata(&pdev->dev, &rng->ops); ret = hwrng_register(&rng->ops); if (ret) - goto err; + return -ENOENT; dev_info(&pdev->dev, "Octeon Random Number Generator\n"); return 0; -err: - devm_iounmap(&pdev->dev, rng->control_status); -err_r: - devm_iounmap(&pdev->dev, rng->result); -err_ports: - devm_kfree(&pdev->dev, rng); - return -ENOENT; } static int __exit octeon_rng_remove(struct platform_device *pdev) diff --git a/drivers/char/hw_random/omap-rng.c b/drivers/char/hw_random/omap-rng.c index 4fbdceb6f773..45e467dcc8c8 100644 --- a/drivers/char/hw_random/omap-rng.c +++ b/drivers/char/hw_random/omap-rng.c @@ -18,16 +18,15 @@ #include <linux/module.h> #include <linux/init.h> #include <linux/random.h> -#include <linux/clk.h> #include <linux/err.h> #include <linux/platform_device.h> #include <linux/hw_random.h> #include <linux/delay.h> +#include <linux/slab.h> +#include <linux/pm_runtime.h> #include <asm/io.h> -#include <plat/cpu.h> - #define RNG_OUT_REG 0x00 /* Output register */ #define RNG_STAT_REG 0x04 /* Status register [0] = STAT_BUSY */ @@ -46,26 +45,36 @@ #define RNG_SYSSTATUS 0x44 /* System status [0] = RESETDONE */ -static void __iomem *rng_base; -static struct clk *rng_ick; -static struct platform_device *rng_dev; +/** + * struct omap_rng_private_data - RNG IP block-specific data + * @base: virtual address of the beginning of the RNG IP block registers + * @mem_res: struct resource * for the IP block registers physical memory + */ +struct omap_rng_private_data { + void __iomem *base; + struct resource *mem_res; +}; -static inline u32 omap_rng_read_reg(int reg) +static inline u32 omap_rng_read_reg(struct omap_rng_private_data *priv, int reg) { - return __raw_readl(rng_base + reg); + return __raw_readl(priv->base + reg); } -static inline void omap_rng_write_reg(int reg, u32 val) +static inline void omap_rng_write_reg(struct omap_rng_private_data *priv, + int reg, u32 val) { - __raw_writel(val, rng_base + reg); + __raw_writel(val, priv->base + reg); } static int omap_rng_data_present(struct hwrng *rng, int wait) { + struct omap_rng_private_data *priv; int data, i; + priv = (struct omap_rng_private_data *)rng->priv; + for (i = 0; i < 20; i++) { - data = omap_rng_read_reg(RNG_STAT_REG) ? 0 : 1; + data = omap_rng_read_reg(priv, RNG_STAT_REG) ? 0 : 1; if (data || !wait) break; /* RNG produces data fast enough (2+ MBit/sec, even @@ -80,9 +89,13 @@ static int omap_rng_data_present(struct hwrng *rng, int wait) static int omap_rng_data_read(struct hwrng *rng, u32 *data) { - *data = omap_rng_read_reg(RNG_OUT_REG); + struct omap_rng_private_data *priv; + + priv = (struct omap_rng_private_data *)rng->priv; + + *data = omap_rng_read_reg(priv, RNG_OUT_REG); - return 4; + return sizeof(u32); } static struct hwrng omap_rng_ops = { @@ -93,69 +106,68 @@ static struct hwrng omap_rng_ops = { static int __devinit omap_rng_probe(struct platform_device *pdev) { - struct resource *res; + struct omap_rng_private_data *priv; int ret; - /* - * A bit ugly, and it will never actually happen but there can - * be only one RNG and this catches any bork - */ - if (rng_dev) - return -EBUSY; - - if (cpu_is_omap24xx()) { - rng_ick = clk_get(&pdev->dev, "ick"); - if (IS_ERR(rng_ick)) { - dev_err(&pdev->dev, "Could not get rng_ick\n"); - ret = PTR_ERR(rng_ick); - return ret; - } else - clk_enable(rng_ick); - } + priv = kzalloc(sizeof(struct omap_rng_private_data), GFP_KERNEL); + if (!priv) { + dev_err(&pdev->dev, "could not allocate memory\n"); + return -ENOMEM; + }; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + omap_rng_ops.priv = (unsigned long)priv; + dev_set_drvdata(&pdev->dev, priv); - rng_base = devm_request_and_ioremap(&pdev->dev, res); - if (!rng_base) { + priv->mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!priv->mem_res) { + ret = -ENOENT; + goto err_ioremap; + } + + priv->base = devm_request_and_ioremap(&pdev->dev, priv->mem_res); + if (!priv->base) { ret = -ENOMEM; goto err_ioremap; } - dev_set_drvdata(&pdev->dev, res); + dev_set_drvdata(&pdev->dev, priv); + + pm_runtime_enable(&pdev->dev); + pm_runtime_get_sync(&pdev->dev); ret = hwrng_register(&omap_rng_ops); if (ret) goto err_register; dev_info(&pdev->dev, "OMAP Random Number Generator ver. %02x\n", - omap_rng_read_reg(RNG_REV_REG)); - omap_rng_write_reg(RNG_MASK_REG, 0x1); + omap_rng_read_reg(priv, RNG_REV_REG)); - rng_dev = pdev; + omap_rng_write_reg(priv, RNG_MASK_REG, 0x1); return 0; err_register: - rng_base = NULL; + priv->base = NULL; + pm_runtime_disable(&pdev->dev); err_ioremap: - if (cpu_is_omap24xx()) { - clk_disable(rng_ick); - clk_put(rng_ick); - } + kfree(priv); + return ret; } static int __exit omap_rng_remove(struct platform_device *pdev) { + struct omap_rng_private_data *priv = dev_get_drvdata(&pdev->dev); + hwrng_unregister(&omap_rng_ops); - omap_rng_write_reg(RNG_MASK_REG, 0x0); + omap_rng_write_reg(priv, RNG_MASK_REG, 0x0); - if (cpu_is_omap24xx()) { - clk_disable(rng_ick); - clk_put(rng_ick); - } + pm_runtime_put_sync(&pdev->dev); + pm_runtime_disable(&pdev->dev); + + release_mem_region(priv->mem_res->start, resource_size(priv->mem_res)); - rng_base = NULL; + kfree(priv); return 0; } @@ -164,13 +176,21 @@ static int __exit omap_rng_remove(struct platform_device *pdev) static int omap_rng_suspend(struct device *dev) { - omap_rng_write_reg(RNG_MASK_REG, 0x0); + struct omap_rng_private_data *priv = dev_get_drvdata(dev); + + omap_rng_write_reg(priv, RNG_MASK_REG, 0x0); + pm_runtime_put_sync(dev); + return 0; } static int omap_rng_resume(struct device *dev) { - omap_rng_write_reg(RNG_MASK_REG, 0x1); + struct omap_rng_private_data *priv = dev_get_drvdata(dev); + + pm_runtime_get_sync(dev); + omap_rng_write_reg(priv, RNG_MASK_REG, 0x1); + return 0; } @@ -198,9 +218,6 @@ static struct platform_driver omap_rng_driver = { static int __init omap_rng_init(void) { - if (!cpu_is_omap16xx() && !cpu_is_omap24xx()) - return -ENODEV; - return platform_driver_register(&omap_rng_driver); } diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c index 3a632673aed5..a1f70407cc9e 100644 --- a/drivers/char/hw_random/pasemi-rng.c +++ b/drivers/char/hw_random/pasemi-rng.c @@ -122,7 +122,7 @@ static int __devinit rng_probe(struct platform_device *ofdev) return err; } -static int __devexit rng_remove(struct platform_device *dev) +static int rng_remove(struct platform_device *dev) { void __iomem *rng_regs = (void __iomem *)pasemi_rng.priv; diff --git a/drivers/char/hw_random/picoxcell-rng.c b/drivers/char/hw_random/picoxcell-rng.c index 97bd891422c7..d4b24c1dd48e 100644 --- a/drivers/char/hw_random/picoxcell-rng.c +++ b/drivers/char/hw_random/picoxcell-rng.c @@ -151,7 +151,7 @@ err_enable: return ret; } -static int __devexit picoxcell_trng_remove(struct platform_device *pdev) +static int picoxcell_trng_remove(struct platform_device *pdev) { hwrng_unregister(&picoxcell_trng); clk_disable(rng_clk); diff --git a/drivers/char/hw_random/ppc4xx-rng.c b/drivers/char/hw_random/ppc4xx-rng.c index c51762c13031..af6506a69cd9 100644 --- a/drivers/char/hw_random/ppc4xx-rng.c +++ b/drivers/char/hw_random/ppc4xx-rng.c @@ -111,7 +111,7 @@ static int __devinit ppc4xx_rng_probe(struct platform_device *dev) return err; } -static int __devexit ppc4xx_rng_remove(struct platform_device *dev) +static int ppc4xx_rng_remove(struct platform_device *dev) { void __iomem *rng_regs = (void __iomem *) ppc4xx_rng.priv; diff --git a/drivers/char/hw_random/timeriomem-rng.c b/drivers/char/hw_random/timeriomem-rng.c index f1a1618db1fb..3a1abc9417e4 100644 --- a/drivers/char/hw_random/timeriomem-rng.c +++ b/drivers/char/hw_random/timeriomem-rng.c @@ -130,7 +130,7 @@ failed: return ret; } -static int __devexit timeriomem_rng_remove(struct platform_device *pdev) +static int timeriomem_rng_remove(struct platform_device *pdev) { del_timer_sync(&timeriomem_rng_timer); hwrng_unregister(&timeriomem_rng_ops); diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c index 5708299507d0..621f595f1a98 100644 --- a/drivers/char/hw_random/virtio-rng.c +++ b/drivers/char/hw_random/virtio-rng.c @@ -119,7 +119,7 @@ static int virtrng_probe(struct virtio_device *vdev) return probe_common(vdev); } -static void __devexit virtrng_remove(struct virtio_device *vdev) +static void virtrng_remove(struct virtio_device *vdev) { remove_common(vdev); } diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 2c29942b1326..053201b062a4 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -1880,7 +1880,7 @@ int ipmi_request_supply_msgs(ipmi_user_t user, struct ipmi_recv_msg *supplied_recv, int priority) { - unsigned char saddr, lun; + unsigned char saddr = 0, lun = 0; int rv; if (!user) @@ -3789,7 +3789,7 @@ static int handle_one_recv_msg(ipmi_smi_t intf, } else if ((msg->rsp[0] == ((IPMI_NETFN_APP_REQUEST|1) << 2)) && (msg->rsp[1] == IPMI_READ_EVENT_MSG_BUFFER_CMD)) { - /* It's an asyncronous event. */ + /* It's an asynchronous event. */ requeue = handle_read_event_rsp(intf, msg); } else { /* It's a response from the local BMC. */ diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c index 83f85cf7fb1b..cfdfecd5bc76 100644 --- a/drivers/char/ipmi/ipmi_si_intf.c +++ b/drivers/char/ipmi/ipmi_si_intf.c @@ -155,7 +155,7 @@ enum si_stat_indexes { /* Number of watchdog pretimeouts. */ SI_STAT_watchdog_pretimeouts, - /* Number of asyncronous messages received. */ + /* Number of asynchronous messages received. */ SI_STAT_incoming_messages, @@ -1836,7 +1836,7 @@ static int hotmod_handler(const char *val, struct kernel_param *kp) return rv; } -static int __devinit hardcode_find_bmc(void) +static int hardcode_find_bmc(void) { int ret = -ENODEV; int i; @@ -2023,7 +2023,7 @@ struct SPMITable { s8 spmi_id[1]; /* A '\0' terminated array starts here. */ }; -static int __devinit try_init_spmi(struct SPMITable *spmi) +static int try_init_spmi(struct SPMITable *spmi) { struct smi_info *info; @@ -2106,7 +2106,7 @@ static int __devinit try_init_spmi(struct SPMITable *spmi) return 0; } -static void __devinit spmi_find_bmc(void) +static void spmi_find_bmc(void) { acpi_status status; struct SPMITable *spmi; @@ -2128,7 +2128,7 @@ static void __devinit spmi_find_bmc(void) } } -static int __devinit ipmi_pnp_probe(struct pnp_dev *dev, +static int ipmi_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { struct acpi_device *acpi_dev; @@ -2228,7 +2228,7 @@ err_free: return -EINVAL; } -static void __devexit ipmi_pnp_remove(struct pnp_dev *dev) +static void ipmi_pnp_remove(struct pnp_dev *dev) { struct smi_info *info = pnp_get_drvdata(dev); @@ -2258,7 +2258,7 @@ struct dmi_ipmi_data { u8 slave_addr; }; -static int __devinit decode_dmi(const struct dmi_header *dm, +static int decode_dmi(const struct dmi_header *dm, struct dmi_ipmi_data *dmi) { const u8 *data = (const u8 *)dm; @@ -2320,7 +2320,7 @@ static int __devinit decode_dmi(const struct dmi_header *dm, return 0; } -static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data) +static void try_init_dmi(struct dmi_ipmi_data *ipmi_data) { struct smi_info *info; @@ -2388,7 +2388,7 @@ static void __devinit try_init_dmi(struct dmi_ipmi_data *ipmi_data) kfree(info); } -static void __devinit dmi_find_bmc(void) +static void dmi_find_bmc(void) { const struct dmi_device *dev = NULL; struct dmi_ipmi_data data; @@ -2424,7 +2424,39 @@ static void ipmi_pci_cleanup(struct smi_info *info) pci_disable_device(pdev); } -static int __devinit ipmi_pci_probe(struct pci_dev *pdev, +static int ipmi_pci_probe_regspacing(struct smi_info *info) +{ + if (info->si_type == SI_KCS) { + unsigned char status; + int regspacing; + + info->io.regsize = DEFAULT_REGSIZE; + info->io.regshift = 0; + info->io_size = 2; + info->handlers = &kcs_smi_handlers; + + /* detect 1, 4, 16byte spacing */ + for (regspacing = DEFAULT_REGSPACING; regspacing <= 16;) { + info->io.regspacing = regspacing; + if (info->io_setup(info)) { + dev_err(info->dev, + "Could not setup I/O space\n"); + return DEFAULT_REGSPACING; + } + /* write invalid cmd */ + info->io.outputb(&info->io, 1, 0x10); + /* read status back */ + status = info->io.inputb(&info->io, 1); + info->io_cleanup(info); + if (status) + return regspacing; + regspacing *= 4; + } + } + return DEFAULT_REGSPACING; +} + +static int ipmi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) { int rv; @@ -2476,8 +2508,8 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, } info->io.addr_data = pci_resource_start(pdev, 0); - info->io.regspacing = DEFAULT_REGSPACING; - info->io.regsize = DEFAULT_REGSPACING; + info->io.regspacing = ipmi_pci_probe_regspacing(info); + info->io.regsize = DEFAULT_REGSIZE; info->io.regshift = 0; info->irq = pdev->irq; @@ -2497,7 +2529,7 @@ static int __devinit ipmi_pci_probe(struct pci_dev *pdev, return 0; } -static void __devexit ipmi_pci_remove(struct pci_dev *pdev) +static void ipmi_pci_remove(struct pci_dev *pdev) { struct smi_info *info = pci_get_drvdata(pdev); cleanup_one_si(info); @@ -2519,7 +2551,7 @@ static struct pci_driver ipmi_pci_driver = { #endif /* CONFIG_PCI */ static struct of_device_id ipmi_match[]; -static int __devinit ipmi_probe(struct platform_device *dev) +static int ipmi_probe(struct platform_device *dev) { #ifdef CONFIG_OF const struct of_device_id *match; @@ -2603,7 +2635,7 @@ static int __devinit ipmi_probe(struct platform_device *dev) return 0; } -static int __devexit ipmi_remove(struct platform_device *dev) +static int ipmi_remove(struct platform_device *dev) { #ifdef CONFIG_OF cleanup_one_si(dev_get_drvdata(&dev->dev)); @@ -3015,7 +3047,7 @@ static inline void wait_for_timer_and_thread(struct smi_info *smi_info) } } -static __devinitdata struct ipmi_default_vals +static struct ipmi_default_vals { int type; int port; @@ -3027,7 +3059,7 @@ static __devinitdata struct ipmi_default_vals { .port = 0 } }; -static void __devinit default_find_bmc(void) +static void default_find_bmc(void) { struct smi_info *info; int i; @@ -3327,7 +3359,7 @@ static int try_smi_init(struct smi_info *new_smi) return rv; } -static int __devinit init_ipmi_si(void) +static int init_ipmi_si(void) { int i; char *str; diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c index 47ff7e470d87..e5d3e3f7a49b 100644 --- a/drivers/char/mbcs.c +++ b/drivers/char/mbcs.c @@ -507,7 +507,7 @@ static int mbcs_gscr_mmap(struct file *fp, struct vm_area_struct *vma) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); - /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ + /* Remap-pfn-range will mark the range VM_IO */ if (remap_pfn_range(vma, vma->vm_start, __pa(soft->gscr_addr) >> PAGE_SHIFT, @@ -799,7 +799,7 @@ static int mbcs_remove(struct cx_dev *dev) return 0; } -static const struct cx_device_id __devinitdata mbcs_id_table[] = { +static const struct cx_device_id mbcs_id_table[] = { { .part_num = MBCS_PART_NUM, .mfg_num = MBCS_MFG_NUM, diff --git a/drivers/char/mem.c b/drivers/char/mem.c index e5eedfa24c91..c6fa3bc2baa8 100644 --- a/drivers/char/mem.c +++ b/drivers/char/mem.c @@ -48,7 +48,7 @@ static inline unsigned long size_inside_page(unsigned long start, } #ifndef ARCH_HAS_VALID_PHYS_ADDR_RANGE -static inline int valid_phys_addr_range(unsigned long addr, size_t count) +static inline int valid_phys_addr_range(phys_addr_t addr, size_t count) { return addr + count <= __pa(high_memory); } @@ -96,7 +96,7 @@ void __weak unxlate_dev_mem_ptr(unsigned long phys, void *addr) static ssize_t read_mem(struct file *file, char __user *buf, size_t count, loff_t *ppos) { - unsigned long p = *ppos; + phys_addr_t p = *ppos; ssize_t read, sz; char *ptr; @@ -153,7 +153,7 @@ static ssize_t read_mem(struct file *file, char __user *buf, static ssize_t write_mem(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { - unsigned long p = *ppos; + phys_addr_t p = *ppos; ssize_t written, sz; unsigned long copied; void *ptr; @@ -226,7 +226,7 @@ int __weak phys_mem_access_prot_allowed(struct file *file, * */ #ifdef pgprot_noncached -static int uncached_access(struct file *file, unsigned long addr) +static int uncached_access(struct file *file, phys_addr_t addr) { #if defined(CONFIG_IA64) /* @@ -258,7 +258,7 @@ static pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn, unsigned long size, pgprot_t vma_prot) { #ifdef pgprot_noncached - unsigned long offset = pfn << PAGE_SHIFT; + phys_addr_t offset = pfn << PAGE_SHIFT; if (uncached_access(file, offset)) return pgprot_noncached(vma_prot); @@ -322,7 +322,7 @@ static int mmap_mem(struct file *file, struct vm_area_struct *vma) vma->vm_ops = &mmap_mem_ops; - /* Remap-pfn-range will mark the range VM_IO and VM_RESERVED */ + /* Remap-pfn-range will mark the range VM_IO */ if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, diff --git a/drivers/char/mmtimer.c b/drivers/char/mmtimer.c index 33dc2298af73..3d6c0671e996 100644 --- a/drivers/char/mmtimer.c +++ b/drivers/char/mmtimer.c @@ -826,7 +826,7 @@ static int __init mmtimer_init(void) /* Allocate list of node ptrs to mmtimer_t's */ timers = kzalloc(sizeof(struct mmtimer_node)*maxn, GFP_KERNEL); - if (timers == NULL) { + if (!timers) { printk(KERN_ERR "%s: failed to allocate memory for device\n", MMTIMER_NAME); goto out3; @@ -848,7 +848,6 @@ static int __init mmtimer_init(void) return 0; out3: - kfree(timers); misc_deregister(&mmtimer_miscdev); out2: free_irq(SGI_MMTIMER_VECTOR, NULL); diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c index 845f97fd1832..e1f60f968fdd 100644 --- a/drivers/char/mspec.c +++ b/drivers/char/mspec.c @@ -286,7 +286,7 @@ mspec_mmap(struct file *file, struct vm_area_struct *vma, atomic_set(&vdata->refcnt, 1); vma->vm_private_data = vdata; - vma->vm_flags |= (VM_IO | VM_RESERVED | VM_PFNMAP | VM_DONTEXPAND); + vma->vm_flags |= VM_IO | VM_PFNMAP | VM_DONTEXPAND | VM_DONTDUMP; if (vdata->type == MSPEC_FETCHOP || vdata->type == MSPEC_UNCACHED) vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); vma->vm_ops = &mspec_vm_ops; diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c index 1d82d5838f0c..164544afd680 100644 --- a/drivers/char/mwave/mwavedd.c +++ b/drivers/char/mwave/mwavedd.c @@ -430,7 +430,7 @@ static ssize_t mwave_write(struct file *file, const char __user *buf, static int register_serial_portandirq(unsigned int port, int irq) { - struct uart_port uart; + struct uart_8250_port uart; switch ( port ) { case 0x3f8: @@ -462,14 +462,14 @@ static int register_serial_portandirq(unsigned int port, int irq) } /* switch */ /* irq is okay */ - memset(&uart, 0, sizeof(struct uart_port)); + memset(&uart, 0, sizeof(uart)); - uart.uartclk = 1843200; - uart.iobase = port; - uart.irq = irq; - uart.iotype = UPIO_PORT; - uart.flags = UPF_SHARE_IRQ; - return serial8250_register_port(&uart); + uart.port.uartclk = 1843200; + uart.port.iobase = port; + uart.port.irq = irq; + uart.port.iotype = UPIO_PORT; + uart.port.flags = UPF_SHARE_IRQ; + return serial8250_register_8250_port(&uart); } diff --git a/drivers/char/nwbutton.c b/drivers/char/nwbutton.c index 04a480f86c6c..cfdfe493c6af 100644 --- a/drivers/char/nwbutton.c +++ b/drivers/char/nwbutton.c @@ -93,9 +93,9 @@ int button_del_callback (void (*callback) (void)) button_callback_list [lp].count = 0; callback_count--; return 0; - }; + } lp--; - }; + } return -EINVAL; } diff --git a/drivers/char/nwflash.c b/drivers/char/nwflash.c index d45c3345b4af..e371480d3639 100644 --- a/drivers/char/nwflash.c +++ b/drivers/char/nwflash.c @@ -30,7 +30,6 @@ #include <asm/hardware/dec21285.h> #include <asm/io.h> -#include <asm/leds.h> #include <asm/mach-types.h> #include <asm/uaccess.h> @@ -179,9 +178,6 @@ static ssize_t flash_write(struct file *file, const char __user *buf, written = 0; - leds_event(led_claim); - leds_event(led_green_on); - nBlock = (int) p >> 16; //block # of 64K bytes /* @@ -258,11 +254,6 @@ static ssize_t flash_write(struct file *file, const char __user *buf, printk(KERN_DEBUG "flash_write: written 0x%X bytes OK.\n", written); } - /* - * restore reg on exit - */ - leds_event(led_release); - mutex_unlock(&nwflash_mutex); return written; @@ -334,11 +325,6 @@ static int erase_block(int nBlock) int temp, temp1; /* - * orange LED == erase - */ - leds_event(led_amber_on); - - /* * reset footbridge to the correct offset 0 (...0..3) */ *CSR_ROMWRITEREG = 0; @@ -446,12 +432,6 @@ static int write_block(unsigned long p, const char __user *buf, int count) unsigned long timeout; unsigned long timeout1; - /* - * red LED == write - */ - leds_event(led_amber_off); - leds_event(led_red_on); - pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p)); /* @@ -558,17 +538,9 @@ static int write_block(unsigned long p, const char __user *buf, int count) pWritePtr - FLASH_BASE); /* - * no LED == waiting - */ - leds_event(led_amber_off); - /* * wait couple ms */ msleep(10); - /* - * red LED == write - */ - leds_event(led_red_on); goto WriteRetry; } else { @@ -583,12 +555,6 @@ static int write_block(unsigned long p, const char __user *buf, int count) } } - /* - * green LED == read/verify - */ - leds_event(led_amber_off); - leds_event(led_green_on); - msleep(10); pWritePtr = (unsigned char *) ((unsigned int) (FLASH_BASE + p)); @@ -617,9 +583,9 @@ static void kick_open(void) * we want to write a bit pattern XXX1 to Xilinx to enable * the write gate, which will be open for about the next 2ms. */ - spin_lock_irqsave(&nw_gpio_lock, flags); + raw_spin_lock_irqsave(&nw_gpio_lock, flags); nw_cpld_modify(CPLD_FLASH_WR_ENABLE, CPLD_FLASH_WR_ENABLE); - spin_unlock_irqrestore(&nw_gpio_lock, flags); + raw_spin_unlock_irqrestore(&nw_gpio_lock, flags); /* * let the ISA bus to catch on... diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c index b304ec052501..3f79a9fb6b1b 100644 --- a/drivers/char/pc8736x_gpio.c +++ b/drivers/char/pc8736x_gpio.c @@ -345,8 +345,7 @@ static void __exit pc8736x_gpio_cleanup(void) unregister_chrdev_region(MKDEV(major,0), PC8736X_GPIO_CT); release_region(pc8736x_gpio_base, PC8736X_GPIO_RANGE); - platform_device_del(pdev); - platform_device_put(pdev); + platform_device_unregister(pdev); } module_init(pc8736x_gpio_init); diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c index 0a484b4a1b02..b66eaa04f8cb 100644 --- a/drivers/char/pcmcia/synclink_cs.c +++ b/drivers/char/pcmcia/synclink_cs.c @@ -549,8 +549,10 @@ static int mgslpc_probe(struct pcmcia_device *link) /* Initialize the struct pcmcia_device structure */ ret = mgslpc_config(link); - if (ret) + if (ret) { + tty_port_destroy(&info->port); return ret; + } mgslpc_add_device(info); @@ -891,6 +893,14 @@ static void rx_ready_async(MGSLPC_INFO *info, int tcd, struct tty_struct *tty) int work = 0; struct mgsl_icount *icount = &info->icount; + if (!tty) { + /* tty is not available anymore */ + issue_command(info, CHA, CMD_RXRESET); + if (debug_level >= DEBUG_LEVEL_ISR) + printk("%s(%d):rx_ready_async(tty=NULL)\n",__FILE__,__LINE__); + return; + } + if (tcd) { /* early termination, get FIFO count from RBCL register */ fifo_count = (unsigned char)(read_reg(info, CHA+RBCL) & 0x1f); @@ -980,7 +990,7 @@ static void tx_done(MGSLPC_INFO *info, struct tty_struct *tty) else #endif { - if (tty->stopped || tty->hw_stopped) { + if (tty && (tty->stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1000,7 +1010,7 @@ static void tx_ready(MGSLPC_INFO *info, struct tty_struct *tty) if (!info->tx_active) return; } else { - if (tty->stopped || tty->hw_stopped) { + if (tty && (tty->stopped || tty->hw_stopped)) { tx_stop(info); return; } @@ -1050,13 +1060,12 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) wake_up_interruptible(&info->status_event_wait_q); wake_up_interruptible(&info->event_wait_q); - if (info->port.flags & ASYNC_CTS_FLOW) { + if (tty && tty_port_cts_enabled(&info->port)) { if (tty->hw_stopped) { if (info->serial_signals & SerialSignal_CTS) { if (debug_level >= DEBUG_LEVEL_ISR) printk("CTS tx start..."); - if (tty) - tty->hw_stopped = 0; + tty->hw_stopped = 0; tx_start(info, tty); info->pending_bh |= BH_TRANSMIT; return; @@ -1065,8 +1074,7 @@ static void cts_change(MGSLPC_INFO *info, struct tty_struct *tty) if (!(info->serial_signals & SerialSignal_CTS)) { if (debug_level >= DEBUG_LEVEL_ISR) printk("CTS tx stop..."); - if (tty) - tty->hw_stopped = 1; + tty->hw_stopped = 1; tx_stop(info); } } @@ -1344,7 +1352,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty) /* TODO:disable interrupts instead of reset to preserve signal states */ reset_device(info); - if (!tty || tty->termios->c_cflag & HUPCL) { + if (!tty || tty->termios.c_cflag & HUPCL) { info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); set_signals(info); } @@ -1385,7 +1393,7 @@ static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty) port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI); get_signals(info); - if (info->netcount || (tty && (tty->termios->c_cflag & CREAD))) + if (info->netcount || (tty && (tty->termios.c_cflag & CREAD))) rx_start(info); spin_unlock_irqrestore(&info->lock,flags); @@ -1398,14 +1406,14 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty) unsigned cflag; int bits_per_char; - if (!tty || !tty->termios) + if (!tty) return; if (debug_level >= DEBUG_LEVEL_INFO) printk("%s(%d):mgslpc_change_params(%s)\n", __FILE__,__LINE__, info->device_name ); - cflag = tty->termios->c_cflag; + cflag = tty->termios.c_cflag; /* if B0 rate (hangup) specified then negate DTR and RTS */ /* otherwise assert DTR and RTS */ @@ -1728,7 +1736,7 @@ static void mgslpc_throttle(struct tty_struct * tty) if (I_IXOFF(tty)) mgslpc_send_xchar(tty, STOP_CHAR(tty)); - if (tty->termios->c_cflag & CRTSCTS) { + if (tty->termios.c_cflag & CRTSCTS) { spin_lock_irqsave(&info->lock,flags); info->serial_signals &= ~SerialSignal_RTS; set_signals(info); @@ -1757,7 +1765,7 @@ static void mgslpc_unthrottle(struct tty_struct * tty) mgslpc_send_xchar(tty, START_CHAR(tty)); } - if (tty->termios->c_cflag & CRTSCTS) { + if (tty->termios.c_cflag & CRTSCTS) { spin_lock_irqsave(&info->lock,flags); info->serial_signals |= SerialSignal_RTS; set_signals(info); @@ -2293,8 +2301,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term tty->driver->name ); /* just return if nothing has changed */ - if ((tty->termios->c_cflag == old_termios->c_cflag) - && (RELEVANT_IFLAG(tty->termios->c_iflag) + if ((tty->termios.c_cflag == old_termios->c_cflag) + && (RELEVANT_IFLAG(tty->termios.c_iflag) == RELEVANT_IFLAG(old_termios->c_iflag))) return; @@ -2302,7 +2310,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term /* Handle transition to B0 status */ if (old_termios->c_cflag & CBAUD && - !(tty->termios->c_cflag & CBAUD)) { + !(tty->termios.c_cflag & CBAUD)) { info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR); spin_lock_irqsave(&info->lock,flags); set_signals(info); @@ -2311,9 +2319,9 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term /* Handle transition away from B0 status */ if (!(old_termios->c_cflag & CBAUD) && - tty->termios->c_cflag & CBAUD) { + tty->termios.c_cflag & CBAUD) { info->serial_signals |= SerialSignal_DTR; - if (!(tty->termios->c_cflag & CRTSCTS) || + if (!(tty->termios.c_cflag & CRTSCTS) || !test_bit(TTY_THROTTLED, &tty->flags)) { info->serial_signals |= SerialSignal_RTS; } @@ -2324,7 +2332,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term /* Handle turning off CRTSCTS */ if (old_termios->c_cflag & CRTSCTS && - !(tty->termios->c_cflag & CRTSCTS)) { + !(tty->termios.c_cflag & CRTSCTS)) { tty->hw_stopped = 0; tx_release(tty); } @@ -2731,6 +2739,8 @@ static void mgslpc_add_device(MGSLPC_INFO *info) #if SYNCLINK_GENERIC_HDLC hdlcdev_init(info); #endif + tty_port_register_device(&info->port, serial_driver, info->line, + &info->p_dev->dev); } static void mgslpc_remove_device(MGSLPC_INFO *remove_info) @@ -2744,10 +2754,12 @@ static void mgslpc_remove_device(MGSLPC_INFO *remove_info) last->next_device = info->next_device; else mgslpc_device_list = info->next_device; + tty_unregister_device(serial_driver, info->line); #if SYNCLINK_GENERIC_HDLC hdlcdev_exit(info); #endif release_resources(info); + tty_port_destroy(&info->port); kfree(info); mgslpc_device_count--; return; @@ -2798,77 +2810,63 @@ static const struct tty_operations mgslpc_ops = { .proc_fops = &mgslpc_proc_fops, }; -static void synclink_cs_cleanup(void) +static int __init synclink_cs_init(void) { int rc; - while(mgslpc_device_list) - mgslpc_remove_device(mgslpc_device_list); - - if (serial_driver) { - if ((rc = tty_unregister_driver(serial_driver))) - printk("%s(%d) failed to unregister tty driver err=%d\n", - __FILE__,__LINE__,rc); - put_tty_driver(serial_driver); + if (break_on_load) { + mgslpc_get_text_ptr(); + BREAKPOINT(); } - pcmcia_unregister_driver(&mgslpc_driver); -} - -static int __init synclink_cs_init(void) -{ - int rc; - - if (break_on_load) { - mgslpc_get_text_ptr(); - BREAKPOINT(); - } - - if ((rc = pcmcia_register_driver(&mgslpc_driver)) < 0) - return rc; - - serial_driver = alloc_tty_driver(MAX_DEVICE_COUNT); - if (!serial_driver) { - rc = -ENOMEM; - goto error; - } + serial_driver = tty_alloc_driver(MAX_DEVICE_COUNT, + TTY_DRIVER_REAL_RAW | + TTY_DRIVER_DYNAMIC_DEV); + if (IS_ERR(serial_driver)) { + rc = PTR_ERR(serial_driver); + goto err; + } - /* Initialize the tty_driver structure */ - - serial_driver->driver_name = "synclink_cs"; - serial_driver->name = "ttySLP"; - serial_driver->major = ttymajor; - serial_driver->minor_start = 64; - serial_driver->type = TTY_DRIVER_TYPE_SERIAL; - serial_driver->subtype = SERIAL_TYPE_NORMAL; - serial_driver->init_termios = tty_std_termios; - serial_driver->init_termios.c_cflag = - B9600 | CS8 | CREAD | HUPCL | CLOCAL; - serial_driver->flags = TTY_DRIVER_REAL_RAW; - tty_set_operations(serial_driver, &mgslpc_ops); - - if ((rc = tty_register_driver(serial_driver)) < 0) { - printk("%s(%d):Couldn't register serial driver\n", - __FILE__,__LINE__); - put_tty_driver(serial_driver); - serial_driver = NULL; - goto error; - } + /* Initialize the tty_driver structure */ + serial_driver->driver_name = "synclink_cs"; + serial_driver->name = "ttySLP"; + serial_driver->major = ttymajor; + serial_driver->minor_start = 64; + serial_driver->type = TTY_DRIVER_TYPE_SERIAL; + serial_driver->subtype = SERIAL_TYPE_NORMAL; + serial_driver->init_termios = tty_std_termios; + serial_driver->init_termios.c_cflag = + B9600 | CS8 | CREAD | HUPCL | CLOCAL; + tty_set_operations(serial_driver, &mgslpc_ops); + + rc = tty_register_driver(serial_driver); + if (rc < 0) { + printk(KERN_ERR "%s(%d):Couldn't register serial driver\n", + __FILE__, __LINE__); + goto err_put_tty; + } - printk("%s %s, tty major#%d\n", - driver_name, driver_version, - serial_driver->major); + rc = pcmcia_register_driver(&mgslpc_driver); + if (rc < 0) + goto err_unreg_tty; - return 0; + printk(KERN_INFO "%s %s, tty major#%d\n", driver_name, driver_version, + serial_driver->major); -error: - synclink_cs_cleanup(); - return rc; + return 0; +err_unreg_tty: + tty_unregister_driver(serial_driver); +err_put_tty: + put_tty_driver(serial_driver); +err: + return rc; } static void __exit synclink_cs_exit(void) { - synclink_cs_cleanup(); + pcmcia_unregister_driver(&mgslpc_driver); + tty_unregister_driver(serial_driver); + put_tty_driver(serial_driver); } module_init(synclink_cs_init); diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c index 3fcf80ff12f2..1cd49241e60e 100644 --- a/drivers/char/ppdev.c +++ b/drivers/char/ppdev.c @@ -251,12 +251,8 @@ static ssize_t pp_write (struct file * file, const char __user * buf, break; } - if (signal_pending (current)) { - if (!bytes_written) { - bytes_written = -EINTR; - } + if (signal_pending (current)) break; - } cond_resched(); } @@ -783,7 +779,8 @@ static int __init ppdev_init (void) err = PTR_ERR(ppdev_class); goto out_chrdev; } - if (parport_register_driver(&pp_driver)) { + err = parport_register_driver(&pp_driver); + if (err < 0) { printk (KERN_WARNING CHRDEV ": unable to register with parport\n"); goto out_class; } diff --git a/drivers/char/ps3flash.c b/drivers/char/ps3flash.c index 6abdde4da2b7..588063ac9517 100644 --- a/drivers/char/ps3flash.c +++ b/drivers/char/ps3flash.c @@ -363,7 +363,7 @@ static struct miscdevice ps3flash_misc = { .fops = &ps3flash_fops, }; -static int __devinit ps3flash_probe(struct ps3_system_bus_device *_dev) +static int ps3flash_probe(struct ps3_system_bus_device *_dev) { struct ps3_storage_device *dev = to_ps3_storage_device(&_dev->core); struct ps3flash_private *priv; diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c index af9437488b6c..91470fdbab2a 100644 --- a/drivers/char/rtc.c +++ b/drivers/char/rtc.c @@ -411,7 +411,7 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel) case RTC_IRQP_READ: case RTC_IRQP_SET: return -EINVAL; - }; + } } #endif diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index f87780502b41..d780295a1473 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -1164,7 +1164,7 @@ static struct acpi_driver sonypi_acpi_driver = { }; #endif -static int __devinit sonypi_create_input_devices(struct platform_device *pdev) +static int sonypi_create_input_devices(struct platform_device *pdev) { struct input_dev *jog_dev; struct input_dev *key_dev; @@ -1225,7 +1225,7 @@ static int __devinit sonypi_create_input_devices(struct platform_device *pdev) return error; } -static int __devinit sonypi_setup_ioports(struct sonypi_device *dev, +static int sonypi_setup_ioports(struct sonypi_device *dev, const struct sonypi_ioport_list *ioport_list) { /* try to detect if sony-laptop is being used and thus @@ -1265,7 +1265,7 @@ static int __devinit sonypi_setup_ioports(struct sonypi_device *dev, return -EBUSY; } -static int __devinit sonypi_setup_irq(struct sonypi_device *dev, +static int sonypi_setup_irq(struct sonypi_device *dev, const struct sonypi_irq_list *irq_list) { while (irq_list->irq) { @@ -1282,7 +1282,7 @@ static int __devinit sonypi_setup_irq(struct sonypi_device *dev, return -EBUSY; } -static void __devinit sonypi_display_info(void) +static void sonypi_display_info(void) { printk(KERN_INFO "sonypi: detected type%d model, " "verbose = %d, fnkeyinit = %s, camera = %s, " @@ -1304,7 +1304,7 @@ static void __devinit sonypi_display_info(void) sonypi_misc_device.minor); } -static int __devinit sonypi_probe(struct platform_device *dev) +static int sonypi_probe(struct platform_device *dev) { const struct sonypi_ioport_list *ioport_list; const struct sonypi_irq_list *irq_list; @@ -1428,12 +1428,12 @@ static int __devinit sonypi_probe(struct platform_device *dev) return error; } -static int __devexit sonypi_remove(struct platform_device *dev) +static int sonypi_remove(struct platform_device *dev) { sonypi_disable(); synchronize_irq(sonypi_device.irq); - flush_work_sync(&sonypi_device.input_work); + flush_work(&sonypi_device.input_work); if (useinput) { input_unregister_device(sonypi_device.input_key_dev); @@ -1456,7 +1456,7 @@ static int __devexit sonypi_remove(struct platform_device *dev) return 0; } -#ifdef CONFIG_PM +#ifdef CONFIG_PM_SLEEP static int old_camera_power; static int sonypi_suspend(struct device *dev) @@ -1491,7 +1491,7 @@ static struct platform_driver sonypi_driver = { .pm = SONYPI_PM, }, .probe = sonypi_probe, - .remove = __devexit_p(sonypi_remove), + .remove = sonypi_remove, .shutdown = sonypi_shutdown, }; diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c index ad264185eb10..34c63f85104d 100644 --- a/drivers/char/tb0219.c +++ b/drivers/char/tb0219.c @@ -284,7 +284,7 @@ static void tb0219_pci_irq_init(void) vr41xx_set_irq_level(TB0219_PCI_SLOT3_PIN, IRQ_LEVEL_LOW); } -static int __devinit tb0219_probe(struct platform_device *dev) +static int tb0219_probe(struct platform_device *dev) { int retval; @@ -318,7 +318,7 @@ static int __devinit tb0219_probe(struct platform_device *dev) return 0; } -static int __devexit tb0219_remove(struct platform_device *dev) +static int tb0219_remove(struct platform_device *dev) { _machine_restart = old_machine_restart; @@ -334,7 +334,7 @@ static struct platform_device *tb0219_platform_device; static struct platform_driver tb0219_device_driver = { .probe = tb0219_probe, - .remove = __devexit_p(tb0219_remove), + .remove = tb0219_remove, .driver = { .name = "TB0219", .owner = THIS_MODULE, diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c index ce29e7cce528..e95e0ab0bd87 100644 --- a/drivers/char/tlclk.c +++ b/drivers/char/tlclk.c @@ -784,8 +784,10 @@ static int __init tlclk_init(void) } tlclk_major = ret; alarm_events = kzalloc( sizeof(struct tlclk_alarms), GFP_KERNEL); - if (!alarm_events) + if (!alarm_events) { + ret = -ENOMEM; goto out1; + } /* Read telecom clock IRQ number (Set by BIOS) */ if (!request_region(TLCLK_BASE, 8, "telco_clock")) { diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c index 6724615a4fdd..93211df52aab 100644 --- a/drivers/char/tpm/tpm.c +++ b/drivers/char/tpm/tpm.c @@ -1168,7 +1168,7 @@ int tpm_release(struct inode *inode, struct file *file) struct tpm_chip *chip = file->private_data; del_singleshot_timer_sync(&chip->user_read_timer); - flush_work_sync(&chip->work); + flush_work(&chip->work); file->private_data = NULL; atomic_set(&chip->data_pending, 0); kzfree(chip->data_buffer); @@ -1182,17 +1182,20 @@ ssize_t tpm_write(struct file *file, const char __user *buf, size_t size, loff_t *off) { struct tpm_chip *chip = file->private_data; - size_t in_size = size, out_size; + size_t in_size = size; + ssize_t out_size; /* cannot perform a write until the read has cleared - either via tpm_read or a user_read_timer timeout */ - while (atomic_read(&chip->data_pending) != 0) - msleep(TPM_TIMEOUT); - - mutex_lock(&chip->buffer_mutex); + either via tpm_read or a user_read_timer timeout. + This also prevents splitted buffered writes from blocking here. + */ + if (atomic_read(&chip->data_pending) != 0) + return -EBUSY; if (in_size > TPM_BUFSIZE) - in_size = TPM_BUFSIZE; + return -E2BIG; + + mutex_lock(&chip->buffer_mutex); if (copy_from_user (chip->data_buffer, (void __user *) buf, in_size)) { @@ -1202,6 +1205,10 @@ ssize_t tpm_write(struct file *file, const char __user *buf, /* atomic tpm command send and result receive */ out_size = tpm_transmit(chip, chip->data_buffer, TPM_BUFSIZE); + if (out_size < 0) { + mutex_unlock(&chip->buffer_mutex); + return out_size; + } atomic_set(&chip->data_pending, out_size); mutex_unlock(&chip->buffer_mutex); @@ -1221,7 +1228,7 @@ ssize_t tpm_read(struct file *file, char __user *buf, int rc; del_singleshot_timer_sync(&chip->user_read_timer); - flush_work_sync(&chip->work); + flush_work(&chip->work); ret_size = atomic_read(&chip->data_pending); if (ret_size > 0) { /* relay data */ ssize_t orig_ret_size = ret_size; @@ -1259,6 +1266,7 @@ void tpm_remove_hardware(struct device *dev) misc_deregister(&chip->vendor.miscdev); sysfs_remove_group(&dev->kobj, chip->vendor.attr_group); + tpm_remove_ppi(&dev->kobj); tpm_bios_log_teardown(chip->bios_dir); /* write it this way to be explicit (chip->dev == dev) */ @@ -1476,7 +1484,7 @@ struct tpm_chip *tpm_register_hardware(struct device *dev, goto put_device; } - if (sys_add_ppi(&dev->kobj)) { + if (tpm_add_ppi(&dev->kobj)) { misc_deregister(&chip->vendor.miscdev); goto put_device; } diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h index 02c266aa2bf7..8ef7649a50aa 100644 --- a/drivers/char/tpm/tpm.h +++ b/drivers/char/tpm/tpm.h @@ -329,10 +329,15 @@ extern int wait_for_tpm_stat(struct tpm_chip *, u8, unsigned long, wait_queue_head_t *); #ifdef CONFIG_ACPI -extern ssize_t sys_add_ppi(struct kobject *parent); +extern int tpm_add_ppi(struct kobject *); +extern void tpm_remove_ppi(struct kobject *); #else -static inline ssize_t sys_add_ppi(struct kobject *parent) +static inline int tpm_add_ppi(struct kobject *parent) { return 0; } + +static inline void tpm_remove_ppi(struct kobject *parent) +{ +} #endif diff --git a/drivers/char/tpm/tpm_i2c_infineon.c b/drivers/char/tpm/tpm_i2c_infineon.c index 5a831aec9d4b..fb447bd0cb61 100644 --- a/drivers/char/tpm/tpm_i2c_infineon.c +++ b/drivers/char/tpm/tpm_i2c_infineon.c @@ -555,7 +555,7 @@ static struct tpm_vendor_specific tpm_tis_i2c = { .miscdev.fops = &tis_ops, }; -static int __devinit tpm_tis_i2c_init(struct device *dev) +static int tpm_tis_i2c_init(struct device *dev) { u32 vendor; int rc = 0; @@ -632,7 +632,7 @@ static const struct i2c_device_id tpm_tis_i2c_table[] = { MODULE_DEVICE_TABLE(i2c, tpm_tis_i2c_table); static SIMPLE_DEV_PM_OPS(tpm_tis_i2c_ops, tpm_pm_suspend, tpm_pm_resume); -static int __devinit tpm_tis_i2c_probe(struct i2c_client *client, +static int tpm_tis_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { int rc; @@ -656,7 +656,7 @@ static int __devinit tpm_tis_i2c_probe(struct i2c_client *client, return rc; } -static int __devexit tpm_tis_i2c_remove(struct i2c_client *client) +static int tpm_tis_i2c_remove(struct i2c_client *client) { struct tpm_chip *chip = tpm_dev.chip; release_locality(chip, chip->vendor.locality, 1); diff --git a/drivers/char/tpm/tpm_ibmvtpm.c b/drivers/char/tpm/tpm_ibmvtpm.c index 88a95ea2ba03..9978609d93b2 100644 --- a/drivers/char/tpm/tpm_ibmvtpm.c +++ b/drivers/char/tpm/tpm_ibmvtpm.c @@ -32,7 +32,7 @@ static const char tpm_ibmvtpm_driver_name[] = "tpm_ibmvtpm"; -static struct vio_device_id tpm_ibmvtpm_device_table[] __devinitdata = { +static struct vio_device_id tpm_ibmvtpm_device_table[] = { { "IBM,vtpm", "IBM,vtpm"}, { "", "" } }; @@ -267,7 +267,7 @@ static int ibmvtpm_crq_send_init(struct ibmvtpm_dev *ibmvtpm) * Return value: * 0 */ -static int __devexit tpm_ibmvtpm_remove(struct vio_dev *vdev) +static int tpm_ibmvtpm_remove(struct vio_dev *vdev) { struct ibmvtpm_dev *ibmvtpm = ibmvtpm_get_data(&vdev->dev); int rc = 0; @@ -580,7 +580,7 @@ static irqreturn_t ibmvtpm_interrupt(int irq, void *vtpm_instance) * 0 - Success * Non-zero - Failure */ -static int __devinit tpm_ibmvtpm_probe(struct vio_dev *vio_dev, +static int tpm_ibmvtpm_probe(struct vio_dev *vio_dev, const struct vio_device_id *id) { struct ibmvtpm_dev *ibmvtpm; diff --git a/drivers/char/tpm/tpm_infineon.c b/drivers/char/tpm/tpm_infineon.c index 3251a44e8ceb..2b480c2960bb 100644 --- a/drivers/char/tpm/tpm_infineon.c +++ b/drivers/char/tpm/tpm_infineon.c @@ -415,7 +415,7 @@ static const struct pnp_device_id tpm_inf_pnp_tbl[] = { MODULE_DEVICE_TABLE(pnp, tpm_inf_pnp_tbl); -static int __devinit tpm_inf_pnp_probe(struct pnp_dev *dev, +static int tpm_inf_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id) { int rc = 0; @@ -594,7 +594,7 @@ err_last: return rc; } -static __devexit void tpm_inf_pnp_remove(struct pnp_dev *dev) +static void tpm_inf_pnp_remove(struct pnp_dev *dev) { struct tpm_chip *chip = pnp_get_drvdata(dev); @@ -655,7 +655,7 @@ static struct pnp_driver tpm_inf_pnp_driver = { .probe = tpm_inf_pnp_probe, .suspend = tpm_inf_pnp_suspend, .resume = tpm_inf_pnp_resume, - .remove = __devexit_p(tpm_inf_pnp_remove) + .remove = tpm_inf_pnp_remove }; static int __init init_inf(void) diff --git a/drivers/char/tpm/tpm_ppi.c b/drivers/char/tpm/tpm_ppi.c index f27b58cfae98..720ebcf29fdf 100644 --- a/drivers/char/tpm/tpm_ppi.c +++ b/drivers/char/tpm/tpm_ppi.c @@ -444,18 +444,20 @@ static struct attribute *ppi_attrs[] = { &dev_attr_vs_operations.attr, NULL, }; static struct attribute_group ppi_attr_grp = { + .name = "ppi", .attrs = ppi_attrs }; -ssize_t sys_add_ppi(struct kobject *parent) +int tpm_add_ppi(struct kobject *parent) { - struct kobject *ppi; - ppi = kobject_create_and_add("ppi", parent); - if (sysfs_create_group(ppi, &ppi_attr_grp)) - return -EFAULT; - else - return 0; + return sysfs_create_group(parent, &ppi_attr_grp); +} +EXPORT_SYMBOL_GPL(tpm_add_ppi); + +void tpm_remove_ppi(struct kobject *parent) +{ + sysfs_remove_group(parent, &ppi_attr_grp); } -EXPORT_SYMBOL_GPL(sys_add_ppi); +EXPORT_SYMBOL_GPL(tpm_remove_ppi); MODULE_LICENSE("GPL"); diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c index 6bdf2671254f..ea31dafbcac2 100644 --- a/drivers/char/tpm/tpm_tis.c +++ b/drivers/char/tpm/tpm_tis.c @@ -729,7 +729,7 @@ static void tpm_tis_reenable_interrupts(struct tpm_chip *chip) #endif #ifdef CONFIG_PNP -static int __devinit tpm_tis_pnp_init(struct pnp_dev *pnp_dev, +static int tpm_tis_pnp_init(struct pnp_dev *pnp_dev, const struct pnp_device_id *pnp_id) { resource_size_t start, len; @@ -769,7 +769,7 @@ static int tpm_tis_pnp_resume(struct pnp_dev *dev) return ret; } -static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { +static struct pnp_device_id tpm_pnp_tbl[] = { {"PNP0C31", 0}, /* TPM */ {"ATM1200", 0}, /* Atmel */ {"IFX0102", 0}, /* Infineon */ @@ -783,7 +783,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = { }; MODULE_DEVICE_TABLE(pnp, tpm_pnp_tbl); -static __devexit void tpm_tis_pnp_remove(struct pnp_dev *dev) +static void tpm_tis_pnp_remove(struct pnp_dev *dev) { struct tpm_chip *chip = pnp_get_drvdata(dev); diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c index 46b77ede84c0..4945bd3d18d0 100644 --- a/drivers/char/ttyprintk.c +++ b/drivers/char/ttyprintk.c @@ -67,7 +67,7 @@ static int tpk_printk(const unsigned char *buf, int count) tmp[tpk_curr + 1] = '\0'; printk(KERN_INFO "%s%s", tpk_tag, tmp); tpk_curr = 0; - if (buf[i + 1] == '\n') + if ((i + 1) < count && buf[i + 1] == '\n') i++; break; case '\n': @@ -178,11 +178,18 @@ static struct tty_driver *ttyprintk_driver; static int __init ttyprintk_init(void) { int ret = -ENOMEM; - void *rp; - ttyprintk_driver = alloc_tty_driver(1); - if (!ttyprintk_driver) - return ret; + tpk_port.port.ops = &null_ops; + mutex_init(&tpk_port.port_write_mutex); + + ttyprintk_driver = tty_alloc_driver(1, + TTY_DRIVER_RESET_TERMIOS | + TTY_DRIVER_REAL_RAW | + TTY_DRIVER_UNNUMBERED_NODE); + if (IS_ERR(ttyprintk_driver)) + return PTR_ERR(ttyprintk_driver); + + tty_port_init(&tpk_port.port); ttyprintk_driver->driver_name = "ttyprintk"; ttyprintk_driver->name = "ttyprintk"; @@ -191,9 +198,8 @@ static int __init ttyprintk_init(void) ttyprintk_driver->type = TTY_DRIVER_TYPE_CONSOLE; ttyprintk_driver->init_termios = tty_std_termios; ttyprintk_driver->init_termios.c_oflag = OPOST | OCRNL | ONOCR | ONLRET; - ttyprintk_driver->flags = TTY_DRIVER_RESET_TERMIOS | - TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV; tty_set_operations(ttyprintk_driver, &ttyprintk_ops); + tty_port_link_device(&tpk_port.port, ttyprintk_driver, 0); ret = tty_register_driver(ttyprintk_driver); if (ret < 0) { @@ -201,23 +207,12 @@ static int __init ttyprintk_init(void) goto error; } - /* create our unnumbered device */ - rp = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 3), NULL, - ttyprintk_driver->name); - if (IS_ERR(rp)) { - printk(KERN_ERR "Couldn't create ttyprintk device\n"); - ret = PTR_ERR(rp); - goto error; - } - - tty_port_init(&tpk_port.port); - tpk_port.port.ops = &null_ops; - mutex_init(&tpk_port.port_write_mutex); - return 0; error: + tty_unregister_driver(ttyprintk_driver); put_tty_driver(ttyprintk_driver); + tty_port_destroy(&tpk_port.port); ttyprintk_driver = NULL; return ret; } diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c index cdf2f5451c76..90493d4ead1f 100644 --- a/drivers/char/virtio_console.c +++ b/drivers/char/virtio_console.c @@ -24,6 +24,8 @@ #include <linux/err.h> #include <linux/freezer.h> #include <linux/fs.h> +#include <linux/splice.h> +#include <linux/pagemap.h> #include <linux/init.h> #include <linux/list.h> #include <linux/poll.h> @@ -474,26 +476,53 @@ static ssize_t send_control_msg(struct port *port, unsigned int event, return 0; } +struct buffer_token { + union { + void *buf; + struct scatterlist *sg; + } u; + /* If sgpages == 0 then buf is used, else sg is used */ + unsigned int sgpages; +}; + +static void reclaim_sg_pages(struct scatterlist *sg, unsigned int nrpages) +{ + int i; + struct page *page; + + for (i = 0; i < nrpages; i++) { + page = sg_page(&sg[i]); + if (!page) + break; + put_page(page); + } + kfree(sg); +} + /* Callers must take the port->outvq_lock */ static void reclaim_consumed_buffers(struct port *port) { - void *buf; + struct buffer_token *tok; unsigned int len; if (!port->portdev) { /* Device has been unplugged. vqs are already gone. */ return; } - while ((buf = virtqueue_get_buf(port->out_vq, &len))) { - kfree(buf); + while ((tok = virtqueue_get_buf(port->out_vq, &len))) { + if (tok->sgpages) + reclaim_sg_pages(tok->u.sg, tok->sgpages); + else + kfree(tok->u.buf); + kfree(tok); port->outvq_full = false; } } -static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count, - bool nonblock) +static ssize_t __send_to_port(struct port *port, struct scatterlist *sg, + int nents, size_t in_count, + struct buffer_token *tok, bool nonblock) { - struct scatterlist sg[1]; struct virtqueue *out_vq; ssize_t ret; unsigned long flags; @@ -505,8 +534,7 @@ static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count, reclaim_consumed_buffers(port); - sg_init_one(sg, in_buf, in_count); - ret = virtqueue_add_buf(out_vq, sg, 1, 0, in_buf, GFP_ATOMIC); + ret = virtqueue_add_buf(out_vq, sg, nents, 0, tok, GFP_ATOMIC); /* Tell Host to go! */ virtqueue_kick(out_vq); @@ -544,6 +572,37 @@ done: return in_count; } +static ssize_t send_buf(struct port *port, void *in_buf, size_t in_count, + bool nonblock) +{ + struct scatterlist sg[1]; + struct buffer_token *tok; + + tok = kmalloc(sizeof(*tok), GFP_ATOMIC); + if (!tok) + return -ENOMEM; + tok->sgpages = 0; + tok->u.buf = in_buf; + + sg_init_one(sg, in_buf, in_count); + + return __send_to_port(port, sg, 1, in_count, tok, nonblock); +} + +static ssize_t send_pages(struct port *port, struct scatterlist *sg, int nents, + size_t in_count, bool nonblock) +{ + struct buffer_token *tok; + + tok = kmalloc(sizeof(*tok), GFP_ATOMIC); + if (!tok) + return -ENOMEM; + tok->sgpages = nents; + tok->u.sg = sg; + + return __send_to_port(port, sg, nents, in_count, tok, nonblock); +} + /* * Give out the data that's requested from the buffer that we have * queued up. @@ -665,6 +724,26 @@ static ssize_t port_fops_read(struct file *filp, char __user *ubuf, return fill_readbuf(port, ubuf, count, true); } +static int wait_port_writable(struct port *port, bool nonblock) +{ + int ret; + + if (will_write_block(port)) { + if (nonblock) + return -EAGAIN; + + ret = wait_event_freezable(port->waitqueue, + !will_write_block(port)); + if (ret < 0) + return ret; + } + /* Port got hot-unplugged. */ + if (!port->guest_connected) + return -ENODEV; + + return 0; +} + static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, size_t count, loff_t *offp) { @@ -681,18 +760,9 @@ static ssize_t port_fops_write(struct file *filp, const char __user *ubuf, nonblock = filp->f_flags & O_NONBLOCK; - if (will_write_block(port)) { - if (nonblock) - return -EAGAIN; - - ret = wait_event_freezable(port->waitqueue, - !will_write_block(port)); - if (ret < 0) - return ret; - } - /* Port got hot-unplugged. */ - if (!port->guest_connected) - return -ENODEV; + ret = wait_port_writable(port, nonblock); + if (ret < 0) + return ret; count = min((size_t)(32 * 1024), count); @@ -725,6 +795,93 @@ out: return ret; } +struct sg_list { + unsigned int n; + unsigned int size; + size_t len; + struct scatterlist *sg; +}; + +static int pipe_to_sg(struct pipe_inode_info *pipe, struct pipe_buffer *buf, + struct splice_desc *sd) +{ + struct sg_list *sgl = sd->u.data; + unsigned int offset, len; + + if (sgl->n == sgl->size) + return 0; + + /* Try lock this page */ + if (buf->ops->steal(pipe, buf) == 0) { + /* Get reference and unlock page for moving */ + get_page(buf->page); + unlock_page(buf->page); + + len = min(buf->len, sd->len); + sg_set_page(&(sgl->sg[sgl->n]), buf->page, len, buf->offset); + } else { + /* Failback to copying a page */ + struct page *page = alloc_page(GFP_KERNEL); + char *src = buf->ops->map(pipe, buf, 1); + char *dst; + + if (!page) + return -ENOMEM; + dst = kmap(page); + + offset = sd->pos & ~PAGE_MASK; + + len = sd->len; + if (len + offset > PAGE_SIZE) + len = PAGE_SIZE - offset; + + memcpy(dst + offset, src + buf->offset, len); + + kunmap(page); + buf->ops->unmap(pipe, buf, src); + + sg_set_page(&(sgl->sg[sgl->n]), page, len, offset); + } + sgl->n++; + sgl->len += len; + + return len; +} + +/* Faster zero-copy write by splicing */ +static ssize_t port_fops_splice_write(struct pipe_inode_info *pipe, + struct file *filp, loff_t *ppos, + size_t len, unsigned int flags) +{ + struct port *port = filp->private_data; + struct sg_list sgl; + ssize_t ret; + struct splice_desc sd = { + .total_len = len, + .flags = flags, + .pos = *ppos, + .u.data = &sgl, + }; + + ret = wait_port_writable(port, filp->f_flags & O_NONBLOCK); + if (ret < 0) + return ret; + + sgl.n = 0; + sgl.len = 0; + sgl.size = pipe->nrbufs; + sgl.sg = kmalloc(sizeof(struct scatterlist) * sgl.size, GFP_KERNEL); + if (unlikely(!sgl.sg)) + return -ENOMEM; + + sg_init_table(sgl.sg, sgl.size); + ret = __splice_from_pipe(pipe, &sd, pipe_to_sg); + if (likely(ret > 0)) + ret = send_pages(port, sgl.sg, sgl.n, sgl.len, true); + + return ret; +} + static unsigned int port_fops_poll(struct file *filp, poll_table *wait) { struct port *port; @@ -856,6 +1013,7 @@ static const struct file_operations port_fops = { .open = port_fops_open, .read = port_fops_read, .write = port_fops_write, + .splice_write = port_fops_splice_write, .poll = port_fops_poll, .release = port_fops_release, .fasync = port_fops_fasync, @@ -1688,7 +1846,7 @@ static void remove_controlq_data(struct ports_device *portdev) * config space to see how many ports the host has spawned. We * initialize each port found. */ -static int __devinit virtcons_probe(struct virtio_device *vdev) +static int virtcons_probe(struct virtio_device *vdev) { struct ports_device *portdev; int err; @@ -1941,7 +2099,17 @@ static int __init init(void) INIT_LIST_HEAD(&pdrvdata.consoles); INIT_LIST_HEAD(&pdrvdata.portdevs); - return register_virtio_driver(&virtio_console); + err = register_virtio_driver(&virtio_console); + if (err < 0) { + pr_err("Error %d registering virtio driver\n", err); + goto free; + } + return 0; +free: + if (pdrvdata.debugfs_dir) + debugfs_remove_recursive(pdrvdata.debugfs_dir); + class_destroy(pdrvdata.class); + return err; } static void __exit fini(void) diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c index 2c5d15beea35..5224da5202d3 100644 --- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c +++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c @@ -595,7 +595,7 @@ static const struct file_operations hwicap_fops = { .llseek = noop_llseek, }; -static int __devinit hwicap_setup(struct device *dev, int id, +static int hwicap_setup(struct device *dev, int id, const struct resource *regs_res, const struct hwicap_driver_config *config, const struct config_registers *config_regs) @@ -717,7 +717,7 @@ static struct hwicap_driver_config fifo_icap_config = { .reset = fifo_icap_reset, }; -static int __devexit hwicap_remove(struct device *dev) +static int hwicap_remove(struct device *dev) { struct hwicap_drvdata *drvdata; @@ -740,7 +740,7 @@ static int __devexit hwicap_remove(struct device *dev) } #ifdef CONFIG_OF -static int __devinit hwicap_of_probe(struct platform_device *op, +static int hwicap_of_probe(struct platform_device *op, const struct hwicap_driver_config *config) { struct resource res; @@ -785,8 +785,8 @@ static inline int hwicap_of_probe(struct platform_device *op, } #endif /* CONFIG_OF */ -static const struct of_device_id __devinitconst hwicap_of_match[]; -static int __devinit hwicap_drv_probe(struct platform_device *pdev) +static const struct of_device_id hwicap_of_match[]; +static int hwicap_drv_probe(struct platform_device *pdev) { const struct of_device_id *match; struct resource *res; @@ -822,14 +822,14 @@ static int __devinit hwicap_drv_probe(struct platform_device *pdev) &buffer_icap_config, regs); } -static int __devexit hwicap_drv_remove(struct platform_device *pdev) +static int hwicap_drv_remove(struct platform_device *pdev) { return hwicap_remove(&pdev->dev); } #ifdef CONFIG_OF /* Match table for device tree binding */ -static const struct of_device_id __devinitconst hwicap_of_match[] = { +static const struct of_device_id hwicap_of_match[] = { { .compatible = "xlnx,opb-hwicap-1.00.b", .data = &buffer_icap_config}, { .compatible = "xlnx,xps-hwicap-1.00.a", .data = &fifo_icap_config}, {}, |