diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-23 21:40:49 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-01-23 21:40:49 -0500 |
| commit | dfd10e7ae60c6c1b24b5d601744b4fd1ecab2f31 (patch) | |
| tree | 59fc5ee5877a4dcb4bd56d2e0d0272089496dba1 /drivers | |
| parent | f2c73464d7b399cf4e0c601c1c7d7b079080fa52 (diff) | |
| parent | 6373bb71875b3f9f73f375952f92e68140b75657 (diff) | |
Merge tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
Pull ARM SoC platform changes from Olof Johansson:
"New core SoC-specific changes.
New platforms:
* Introduction of a vendor, Hisilicon, and one of their SoCs with
some random numerical product name.
* Introduction of EFM32, embedded platform from Silicon Labs (ARMv7m,
i.e. !MMU).
* Marvell Berlin series of SoCs, which include the one in Chromecast.
* MOXA platform support, ARM9-based platform used mostly in
industrial products
* Support for Freescale's i.MX50 SoC.
Other work:
* Renesas work for new platforms and drivers, and conversion over to
more multiplatform-friendly device registration schemes.
* SMP support for Allwinner sunxi platforms.
* ... plus a bunch of other stuff across various platforms"
* tag 'soc-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc: (201 commits)
ARM: tegra: fix tegra_powergate_sequence_power_up() inline
ARM: msm_defconfig: Update for multi-platform
ARM: msm: Move MSM's DT based hardware to multi-platform support
ARM: msm: Only build timer.c if required
ARM: msm: Only build clock.c on proc_comm based platforms
ARM: ux500: Enable system suspend with WFI support
ARM: ux500: turn on PRINTK_TIME in u8500_defconfig
ARM: shmobile: r8a7790: Fix I2C controller names
ARM: msm: Simplify ARCH_MSM_DT config
ARM: msm: Add support for MSM8974 SoC
ARM: sunxi: select ARM_PSCI
MAINTAINERS: Update Allwinner sunXi maintainer files
ARM: sunxi: Select RESET_CONTROLLER
ARM: imx: improve the comment of CCM lpm SW workaround
ARM: imx: improve status check of clock gate
ARM: imx: add necessary interface for pfd
ARM: imx_v6_v7_defconfig: Select CONFIG_REGULATOR_PFUZE100
ARM: imx_v6_v7_defconfig: Select MX35 and MX50 device tree support
ARM: imx: Add cpu frequency scaling support
ARM i.MX35: Add devicetree support.
...
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/Makefile | 2 | ||||
| -rw-r--r-- | drivers/clocksource/Makefile | 2 | ||||
| -rw-r--r-- | drivers/irqchip/Kconfig | 4 | ||||
| -rw-r--r-- | drivers/irqchip/Makefile | 1 | ||||
| -rw-r--r-- | drivers/irqchip/irq-dw-apb-ictl.c | 150 | ||||
| -rw-r--r-- | drivers/reset/Makefile | 1 | ||||
| -rw-r--r-- | drivers/reset/reset-sunxi.c | 175 |
7 files changed, 333 insertions, 2 deletions
diff --git a/drivers/Makefile b/drivers/Makefile index 3cc8214f9b26..8e3b8b06c0b2 100644 --- a/drivers/Makefile +++ b/drivers/Makefile | |||
| @@ -118,7 +118,7 @@ obj-$(CONFIG_SGI_SN) += sn/ | |||
| 118 | obj-y += firmware/ | 118 | obj-y += firmware/ |
| 119 | obj-$(CONFIG_CRYPTO) += crypto/ | 119 | obj-$(CONFIG_CRYPTO) += crypto/ |
| 120 | obj-$(CONFIG_SUPERH) += sh/ | 120 | obj-$(CONFIG_SUPERH) += sh/ |
| 121 | obj-$(CONFIG_ARCH_SHMOBILE) += sh/ | 121 | obj-$(CONFIG_ARCH_SHMOBILE_LEGACY) += sh/ |
| 122 | ifndef CONFIG_ARCH_USES_GETTIMEOFFSET | 122 | ifndef CONFIG_ARCH_USES_GETTIMEOFFSET |
| 123 | obj-y += clocksource/ | 123 | obj-y += clocksource/ |
| 124 | endif | 124 | endif |
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 358358d87b6d..c7ca50a9c232 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile | |||
| @@ -26,7 +26,7 @@ obj-$(CONFIG_SUN5I_HSTIMER) += timer-sun5i.o | |||
| 26 | obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o | 26 | obj-$(CONFIG_ARCH_TEGRA) += tegra20_timer.o |
| 27 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o | 27 | obj-$(CONFIG_VT8500_TIMER) += vt8500_timer.o |
| 28 | obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o | 28 | obj-$(CONFIG_ARCH_NSPIRE) += zevio-timer.o |
| 29 | obj-$(CONFIG_ARCH_BCM) += bcm_kona_timer.o | 29 | obj-$(CONFIG_ARCH_BCM_MOBILE) += bcm_kona_timer.o |
| 30 | obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o | 30 | obj-$(CONFIG_CADENCE_TTC_TIMER) += cadence_ttc_timer.o |
| 31 | obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o | 31 | obj-$(CONFIG_CLKSRC_EFM32) += time-efm32.o |
| 32 | obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o | 32 | obj-$(CONFIG_CLKSRC_EXYNOS_MCT) += exynos_mct.o |
diff --git a/drivers/irqchip/Kconfig b/drivers/irqchip/Kconfig index 3792a1aa52b8..940638ddc982 100644 --- a/drivers/irqchip/Kconfig +++ b/drivers/irqchip/Kconfig | |||
| @@ -30,6 +30,10 @@ config ARM_VIC_NR | |||
| 30 | The maximum number of VICs available in the system, for | 30 | The maximum number of VICs available in the system, for |
| 31 | power management. | 31 | power management. |
| 32 | 32 | ||
| 33 | config DW_APB_ICTL | ||
| 34 | bool | ||
| 35 | select IRQ_DOMAIN | ||
| 36 | |||
| 33 | config IMGPDC_IRQ | 37 | config IMGPDC_IRQ |
| 34 | bool | 38 | bool |
| 35 | select GENERIC_IRQ_CHIP | 39 | select GENERIC_IRQ_CHIP |
diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index c60b9010b152..6427323af4c3 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile | |||
| @@ -6,6 +6,7 @@ obj-$(CONFIG_ARCH_MMP) += irq-mmp.o | |||
| 6 | obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o | 6 | obj-$(CONFIG_ARCH_MVEBU) += irq-armada-370-xp.o |
| 7 | obj-$(CONFIG_ARCH_MXS) += irq-mxs.o | 7 | obj-$(CONFIG_ARCH_MXS) += irq-mxs.o |
| 8 | obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o | 8 | obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o |
| 9 | obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o | ||
| 9 | obj-$(CONFIG_METAG) += irq-metag-ext.o | 10 | obj-$(CONFIG_METAG) += irq-metag-ext.o |
| 10 | obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o | 11 | obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o |
| 11 | obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o | 12 | obj-$(CONFIG_ARCH_MOXART) += irq-moxart.o |
diff --git a/drivers/irqchip/irq-dw-apb-ictl.c b/drivers/irqchip/irq-dw-apb-ictl.c new file mode 100644 index 000000000000..31e231e1f566 --- /dev/null +++ b/drivers/irqchip/irq-dw-apb-ictl.c | |||
| @@ -0,0 +1,150 @@ | |||
| 1 | /* | ||
| 2 | * Synopsys DW APB ICTL irqchip driver. | ||
| 3 | * | ||
| 4 | * Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com> | ||
| 5 | * | ||
| 6 | * based on GPL'ed 2.6 kernel sources | ||
| 7 | * (c) Marvell International Ltd. | ||
| 8 | * | ||
| 9 | * This file is licensed under the terms of the GNU General Public | ||
| 10 | * License version 2. This program is licensed "as is" without any | ||
| 11 | * warranty of any kind, whether express or implied. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/io.h> | ||
| 15 | #include <linux/irq.h> | ||
| 16 | #include <linux/irqchip/chained_irq.h> | ||
| 17 | #include <linux/of_address.h> | ||
| 18 | #include <linux/of_irq.h> | ||
| 19 | |||
| 20 | #include "irqchip.h" | ||
| 21 | |||
| 22 | #define APB_INT_ENABLE_L 0x00 | ||
| 23 | #define APB_INT_ENABLE_H 0x04 | ||
| 24 | #define APB_INT_MASK_L 0x08 | ||
| 25 | #define APB_INT_MASK_H 0x0c | ||
| 26 | #define APB_INT_FINALSTATUS_L 0x30 | ||
| 27 | #define APB_INT_FINALSTATUS_H 0x34 | ||
| 28 | |||
| 29 | static void dw_apb_ictl_handler(unsigned int irq, struct irq_desc *desc) | ||
| 30 | { | ||
| 31 | struct irq_chip *chip = irq_get_chip(irq); | ||
| 32 | struct irq_chip_generic *gc = irq_get_handler_data(irq); | ||
| 33 | struct irq_domain *d = gc->private; | ||
| 34 | u32 stat; | ||
| 35 | int n; | ||
| 36 | |||
| 37 | chained_irq_enter(chip, desc); | ||
| 38 | |||
| 39 | for (n = 0; n < gc->num_ct; n++) { | ||
| 40 | stat = readl_relaxed(gc->reg_base + | ||
| 41 | APB_INT_FINALSTATUS_L + 4 * n); | ||
| 42 | while (stat) { | ||
| 43 | u32 hwirq = ffs(stat) - 1; | ||
| 44 | generic_handle_irq(irq_find_mapping(d, | ||
| 45 | gc->irq_base + hwirq + 32 * n)); | ||
| 46 | stat &= ~(1 << hwirq); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | chained_irq_exit(chip, desc); | ||
| 51 | } | ||
| 52 | |||
| 53 | static int __init dw_apb_ictl_init(struct device_node *np, | ||
| 54 | struct device_node *parent) | ||
| 55 | { | ||
| 56 | unsigned int clr = IRQ_NOREQUEST | IRQ_NOPROBE | IRQ_NOAUTOEN; | ||
| 57 | struct resource r; | ||
| 58 | struct irq_domain *domain; | ||
| 59 | struct irq_chip_generic *gc; | ||
| 60 | void __iomem *iobase; | ||
| 61 | int ret, nrirqs, irq; | ||
| 62 | u32 reg; | ||
| 63 | |||
| 64 | /* Map the parent interrupt for the chained handler */ | ||
| 65 | irq = irq_of_parse_and_map(np, 0); | ||
| 66 | if (irq <= 0) { | ||
| 67 | pr_err("%s: unable to parse irq\n", np->full_name); | ||
| 68 | return -EINVAL; | ||
| 69 | } | ||
| 70 | |||
| 71 | ret = of_address_to_resource(np, 0, &r); | ||
| 72 | if (ret) { | ||
| 73 | pr_err("%s: unable to get resource\n", np->full_name); | ||
| 74 | return ret; | ||
| 75 | } | ||
| 76 | |||
| 77 | if (!request_mem_region(r.start, resource_size(&r), np->full_name)) { | ||
| 78 | pr_err("%s: unable to request mem region\n", np->full_name); | ||
| 79 | return -ENOMEM; | ||
| 80 | } | ||
| 81 | |||
| 82 | iobase = ioremap(r.start, resource_size(&r)); | ||
| 83 | if (!iobase) { | ||
| 84 | pr_err("%s: unable to map resource\n", np->full_name); | ||
| 85 | ret = -ENOMEM; | ||
| 86 | goto err_release; | ||
| 87 | } | ||
| 88 | |||
| 89 | /* | ||
| 90 | * DW IP can be configured to allow 2-64 irqs. We can determine | ||
| 91 | * the number of irqs supported by writing into enable register | ||
| 92 | * and look for bits not set, as corresponding flip-flops will | ||
| 93 | * have been removed by sythesis tool. | ||
| 94 | */ | ||
| 95 | |||
| 96 | /* mask and enable all interrupts */ | ||
| 97 | writel(~0, iobase + APB_INT_MASK_L); | ||
| 98 | writel(~0, iobase + APB_INT_MASK_H); | ||
| 99 | writel(~0, iobase + APB_INT_ENABLE_L); | ||
| 100 | writel(~0, iobase + APB_INT_ENABLE_H); | ||
| 101 | |||
| 102 | reg = readl(iobase + APB_INT_ENABLE_H); | ||
| 103 | if (reg) | ||
| 104 | nrirqs = 32 + fls(reg); | ||
| 105 | else | ||
| 106 | nrirqs = fls(readl(iobase + APB_INT_ENABLE_L)); | ||
| 107 | |||
| 108 | domain = irq_domain_add_linear(np, nrirqs, | ||
| 109 | &irq_generic_chip_ops, NULL); | ||
| 110 | if (!domain) { | ||
| 111 | pr_err("%s: unable to add irq domain\n", np->full_name); | ||
| 112 | ret = -ENOMEM; | ||
| 113 | goto err_unmap; | ||
| 114 | } | ||
| 115 | |||
| 116 | ret = irq_alloc_domain_generic_chips(domain, 32, (nrirqs > 32) ? 2 : 1, | ||
| 117 | np->name, handle_level_irq, clr, 0, | ||
| 118 | IRQ_GC_INIT_MASK_CACHE); | ||
| 119 | if (ret) { | ||
| 120 | pr_err("%s: unable to alloc irq domain gc\n", np->full_name); | ||
| 121 | goto err_unmap; | ||
| 122 | } | ||
| 123 | |||
| 124 | gc = irq_get_domain_generic_chip(domain, 0); | ||
| 125 | gc->private = domain; | ||
| 126 | gc->reg_base = iobase; | ||
| 127 | |||
| 128 | gc->chip_types[0].regs.mask = APB_INT_MASK_L; | ||
| 129 | gc->chip_types[0].chip.irq_mask = irq_gc_mask_set_bit; | ||
| 130 | gc->chip_types[0].chip.irq_unmask = irq_gc_mask_clr_bit; | ||
| 131 | |||
| 132 | if (nrirqs > 32) { | ||
| 133 | gc->chip_types[1].regs.mask = APB_INT_MASK_H; | ||
| 134 | gc->chip_types[1].chip.irq_mask = irq_gc_mask_set_bit; | ||
| 135 | gc->chip_types[1].chip.irq_unmask = irq_gc_mask_clr_bit; | ||
| 136 | } | ||
| 137 | |||
| 138 | irq_set_handler_data(irq, gc); | ||
| 139 | irq_set_chained_handler(irq, dw_apb_ictl_handler); | ||
| 140 | |||
| 141 | return 0; | ||
| 142 | |||
| 143 | err_unmap: | ||
| 144 | iounmap(iobase); | ||
| 145 | err_release: | ||
| 146 | release_mem_region(r.start, resource_size(&r)); | ||
| 147 | return ret; | ||
| 148 | } | ||
| 149 | IRQCHIP_DECLARE(dw_apb_ictl, | ||
| 150 | "snps,dw-apb-ictl", dw_apb_ictl_init); | ||
diff --git a/drivers/reset/Makefile b/drivers/reset/Makefile index 1e2d83f2b995..cc29832c9638 100644 --- a/drivers/reset/Makefile +++ b/drivers/reset/Makefile | |||
| @@ -1 +1,2 @@ | |||
| 1 | obj-$(CONFIG_RESET_CONTROLLER) += core.o | 1 | obj-$(CONFIG_RESET_CONTROLLER) += core.o |
| 2 | obj-$(CONFIG_ARCH_SUNXI) += reset-sunxi.o | ||
diff --git a/drivers/reset/reset-sunxi.c b/drivers/reset/reset-sunxi.c new file mode 100644 index 000000000000..695bd3496eba --- /dev/null +++ b/drivers/reset/reset-sunxi.c | |||
| @@ -0,0 +1,175 @@ | |||
| 1 | /* | ||
| 2 | * Allwinner SoCs Reset Controller driver | ||
| 3 | * | ||
| 4 | * Copyright 2013 Maxime Ripard | ||
| 5 | * | ||
| 6 | * Maxime Ripard <maxime.ripard@free-electrons.com> | ||
| 7 | * | ||
| 8 | * This program is free software; you can redistribute it and/or modify | ||
| 9 | * it under the terms of the GNU General Public License as published by | ||
| 10 | * the Free Software Foundation; either version 2 of the License, or | ||
| 11 | * (at your option) any later version. | ||
| 12 | */ | ||
| 13 | |||
| 14 | #include <linux/err.h> | ||
| 15 | #include <linux/io.h> | ||
| 16 | #include <linux/module.h> | ||
| 17 | #include <linux/of.h> | ||
| 18 | #include <linux/of_address.h> | ||
| 19 | #include <linux/platform_device.h> | ||
| 20 | #include <linux/reset-controller.h> | ||
| 21 | #include <linux/slab.h> | ||
| 22 | #include <linux/spinlock.h> | ||
| 23 | #include <linux/types.h> | ||
| 24 | |||
| 25 | struct sunxi_reset_data { | ||
| 26 | spinlock_t lock; | ||
| 27 | void __iomem *membase; | ||
| 28 | struct reset_controller_dev rcdev; | ||
| 29 | }; | ||
| 30 | |||
| 31 | static int sunxi_reset_assert(struct reset_controller_dev *rcdev, | ||
| 32 | unsigned long id) | ||
| 33 | { | ||
| 34 | struct sunxi_reset_data *data = container_of(rcdev, | ||
| 35 | struct sunxi_reset_data, | ||
| 36 | rcdev); | ||
| 37 | int bank = id / BITS_PER_LONG; | ||
| 38 | int offset = id % BITS_PER_LONG; | ||
| 39 | unsigned long flags; | ||
| 40 | u32 reg; | ||
| 41 | |||
| 42 | spin_lock_irqsave(&data->lock, flags); | ||
| 43 | |||
| 44 | reg = readl(data->membase + (bank * 4)); | ||
| 45 | writel(reg & ~BIT(offset), data->membase + (bank * 4)); | ||
| 46 | |||
| 47 | spin_unlock_irqrestore(&data->lock, flags); | ||
| 48 | |||
| 49 | return 0; | ||
| 50 | } | ||
| 51 | |||
| 52 | static int sunxi_reset_deassert(struct reset_controller_dev *rcdev, | ||
| 53 | unsigned long id) | ||
| 54 | { | ||
| 55 | struct sunxi_reset_data *data = container_of(rcdev, | ||
| 56 | struct sunxi_reset_data, | ||
| 57 | rcdev); | ||
| 58 | int bank = id / BITS_PER_LONG; | ||
| 59 | int offset = id % BITS_PER_LONG; | ||
| 60 | unsigned long flags; | ||
| 61 | u32 reg; | ||
| 62 | |||
| 63 | spin_lock_irqsave(&data->lock, flags); | ||
| 64 | |||
| 65 | reg = readl(data->membase + (bank * 4)); | ||
| 66 | writel(reg | BIT(offset), data->membase + (bank * 4)); | ||
| 67 | |||
| 68 | spin_unlock_irqrestore(&data->lock, flags); | ||
| 69 | |||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | static struct reset_control_ops sunxi_reset_ops = { | ||
| 74 | .assert = sunxi_reset_assert, | ||
| 75 | .deassert = sunxi_reset_deassert, | ||
| 76 | }; | ||
| 77 | |||
| 78 | static int sunxi_reset_init(struct device_node *np) | ||
| 79 | { | ||
| 80 | struct sunxi_reset_data *data; | ||
| 81 | struct resource res; | ||
| 82 | resource_size_t size; | ||
| 83 | int ret; | ||
| 84 | |||
| 85 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
| 86 | if (!data) | ||
| 87 | return -ENOMEM; | ||
| 88 | |||
| 89 | ret = of_address_to_resource(np, 0, &res); | ||
| 90 | if (ret) | ||
| 91 | goto err_alloc; | ||
| 92 | |||
| 93 | size = resource_size(&res); | ||
| 94 | if (!request_mem_region(res.start, size, np->name)) { | ||
| 95 | ret = -EBUSY; | ||
| 96 | goto err_alloc; | ||
| 97 | } | ||
| 98 | |||
| 99 | data->membase = ioremap(res.start, size); | ||
| 100 | if (!data->membase) { | ||
| 101 | ret = -ENOMEM; | ||
| 102 | goto err_alloc; | ||
| 103 | } | ||
| 104 | |||
| 105 | data->rcdev.owner = THIS_MODULE; | ||
| 106 | data->rcdev.nr_resets = size * 32; | ||
| 107 | data->rcdev.ops = &sunxi_reset_ops; | ||
| 108 | data->rcdev.of_node = np; | ||
| 109 | reset_controller_register(&data->rcdev); | ||
| 110 | |||
| 111 | return 0; | ||
| 112 | |||
| 113 | err_alloc: | ||
| 114 | kfree(data); | ||
| 115 | return ret; | ||
| 116 | }; | ||
| 117 | |||
| 118 | /* | ||
| 119 | * These are the reset controller we need to initialize early on in | ||
| 120 | * our system, before we can even think of using a regular device | ||
| 121 | * driver for it. | ||
| 122 | */ | ||
| 123 | static const struct of_device_id sunxi_early_reset_dt_ids[] __initdata = { | ||
| 124 | { .compatible = "allwinner,sun6i-a31-ahb1-reset", }, | ||
| 125 | { /* sentinel */ }, | ||
| 126 | }; | ||
| 127 | |||
| 128 | void __init sun6i_reset_init(void) | ||
| 129 | { | ||
| 130 | struct device_node *np; | ||
| 131 | |||
| 132 | for_each_matching_node(np, sunxi_early_reset_dt_ids) | ||
| 133 | sunxi_reset_init(np); | ||
| 134 | } | ||
| 135 | |||
| 136 | /* | ||
| 137 | * And these are the controllers we can register through the regular | ||
| 138 | * device model. | ||
| 139 | */ | ||
| 140 | static const struct of_device_id sunxi_reset_dt_ids[] = { | ||
| 141 | { .compatible = "allwinner,sun6i-a31-clock-reset", }, | ||
| 142 | { /* sentinel */ }, | ||
| 143 | }; | ||
| 144 | MODULE_DEVICE_TABLE(of, sunxi_reset_dt_ids); | ||
| 145 | |||
| 146 | static int sunxi_reset_probe(struct platform_device *pdev) | ||
| 147 | { | ||
| 148 | return sunxi_reset_init(pdev->dev.of_node); | ||
| 149 | } | ||
| 150 | |||
| 151 | static int sunxi_reset_remove(struct platform_device *pdev) | ||
| 152 | { | ||
| 153 | struct sunxi_reset_data *data = platform_get_drvdata(pdev); | ||
| 154 | |||
| 155 | reset_controller_unregister(&data->rcdev); | ||
| 156 | iounmap(data->membase); | ||
| 157 | kfree(data); | ||
| 158 | |||
| 159 | return 0; | ||
| 160 | } | ||
| 161 | |||
| 162 | static struct platform_driver sunxi_reset_driver = { | ||
| 163 | .probe = sunxi_reset_probe, | ||
| 164 | .remove = sunxi_reset_remove, | ||
| 165 | .driver = { | ||
| 166 | .name = "sunxi-reset", | ||
| 167 | .owner = THIS_MODULE, | ||
| 168 | .of_match_table = sunxi_reset_dt_ids, | ||
| 169 | }, | ||
| 170 | }; | ||
| 171 | module_platform_driver(sunxi_reset_driver); | ||
| 172 | |||
| 173 | MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com"); | ||
| 174 | MODULE_DESCRIPTION("Allwinner SoCs Reset Controller Driver"); | ||
| 175 | MODULE_LICENSE("GPL"); | ||
