From df46bb1909d92eedccd4216c88e43f75cb0b2901 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 21 Feb 2018 15:31:32 +0000 Subject: irqchip: Remove metag irqchip drivers Now that arch/metag/ has been removed, remove the two metag irqchip drivers. They are of no value without the architecture code. - irq-metag: Meta internal (HWSTATMETA) interrupt code. - irq-metag-ext: Meta External interrupt code. Signed-off-by: James Hogan Cc: Thomas Gleixner Cc: Jason Cooper Cc: Marc Zyngier Cc: linux-metag@vger.kernel.org --- drivers/irqchip/Makefile | 2 - drivers/irqchip/irq-metag-ext.c | 871 ---------------------------------------- drivers/irqchip/irq-metag.c | 343 ---------------- 3 files changed, 1216 deletions(-) delete mode 100644 drivers/irqchip/irq-metag-ext.c delete mode 100644 drivers/irqchip/irq-metag.c (limited to 'drivers') diff --git a/drivers/irqchip/Makefile b/drivers/irqchip/Makefile index d27e3e3619e0..b5b1f4c93413 100644 --- a/drivers/irqchip/Makefile +++ b/drivers/irqchip/Makefile @@ -15,8 +15,6 @@ obj-$(CONFIG_IRQ_MXS) += irq-mxs.o obj-$(CONFIG_ARCH_TEGRA) += irq-tegra.o obj-$(CONFIG_ARCH_S3C24XX) += irq-s3c24xx.o obj-$(CONFIG_DW_APB_ICTL) += irq-dw-apb-ictl.o -obj-$(CONFIG_METAG) += irq-metag-ext.o -obj-$(CONFIG_METAG_PERFCOUNTER_IRQS) += irq-metag.o obj-$(CONFIG_CLPS711X_IRQCHIP) += irq-clps711x.o obj-$(CONFIG_OMPIC) += irq-ompic.o obj-$(CONFIG_OR1K_PIC) += irq-or1k-pic.o diff --git a/drivers/irqchip/irq-metag-ext.c b/drivers/irqchip/irq-metag-ext.c deleted file mode 100644 index e67483161f0f..000000000000 --- a/drivers/irqchip/irq-metag-ext.c +++ /dev/null @@ -1,871 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Meta External interrupt code. - * - * Copyright (C) 2005-2012 Imagination Technologies Ltd. - * - * External interrupts on Meta are configured at two-levels, in the CPU core and - * in the external trigger block. Interrupts from SoC peripherals are - * multiplexed onto a single Meta CPU "trigger" - traditionally it has always - * been trigger 2 (TR2). For info on how de-multiplexing happens check out - * meta_intc_irq_demux(). - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define HWSTAT_STRIDE 8 -#define HWVEC_BLK_STRIDE 0x1000 - -/** - * struct meta_intc_priv - private meta external interrupt data - * @nr_banks: Number of interrupt banks - * @domain: IRQ domain for all banks of external IRQs - * @unmasked: Record of unmasked IRQs - * @levels_altered: Record of altered level bits - */ -struct meta_intc_priv { - unsigned int nr_banks; - struct irq_domain *domain; - - unsigned long unmasked[4]; - -#ifdef CONFIG_METAG_SUSPEND_MEM - unsigned long levels_altered[4]; -#endif -}; - -/* Private data for the one and only external interrupt controller */ -static struct meta_intc_priv meta_intc_priv; - -/** - * meta_intc_offset() - Get the offset into the bank of a hardware IRQ number - * @hw: Hardware IRQ number (within external trigger block) - * - * Returns: Bit offset into the IRQ's bank registers - */ -static unsigned int meta_intc_offset(irq_hw_number_t hw) -{ - return hw & 0x1f; -} - -/** - * meta_intc_bank() - Get the bank number of a hardware IRQ number - * @hw: Hardware IRQ number (within external trigger block) - * - * Returns: Bank number indicating which register the IRQ's bits are - */ -static unsigned int meta_intc_bank(irq_hw_number_t hw) -{ - return hw >> 5; -} - -/** - * meta_intc_stat_addr() - Get the address of a HWSTATEXT register - * @hw: Hardware IRQ number (within external trigger block) - * - * Returns: Address of a HWSTATEXT register containing the status bit for - * the specified hardware IRQ number - */ -static void __iomem *meta_intc_stat_addr(irq_hw_number_t hw) -{ - return (void __iomem *)(HWSTATEXT + - HWSTAT_STRIDE * meta_intc_bank(hw)); -} - -/** - * meta_intc_level_addr() - Get the address of a HWLEVELEXT register - * @hw: Hardware IRQ number (within external trigger block) - * - * Returns: Address of a HWLEVELEXT register containing the sense bit for - * the specified hardware IRQ number - */ -static void __iomem *meta_intc_level_addr(irq_hw_number_t hw) -{ - return (void __iomem *)(HWLEVELEXT + - HWSTAT_STRIDE * meta_intc_bank(hw)); -} - -/** - * meta_intc_mask_addr() - Get the address of a HWMASKEXT register - * @hw: Hardware IRQ number (within external trigger block) - * - * Returns: Address of a HWMASKEXT register containing the mask bit for the - * specified hardware IRQ number - */ -static void __iomem *meta_intc_mask_addr(irq_hw_number_t hw) -{ - return (void __iomem *)(HWMASKEXT + - HWSTAT_STRIDE * meta_intc_bank(hw)); -} - -/** - * meta_intc_vec_addr() - Get the vector address of a hardware interrupt - * @hw: Hardware IRQ number (within external trigger block) - * - * Returns: Address of a HWVECEXT register controlling the core trigger to - * vector the IRQ onto - */ -static inline void __iomem *meta_intc_vec_addr(irq_hw_number_t hw) -{ - return (void __iomem *)(HWVEC0EXT + - HWVEC_BLK_STRIDE * meta_intc_bank(hw) + - HWVECnEXT_STRIDE * meta_intc_offset(hw)); -} - -/** - * meta_intc_startup_irq() - set up an external irq - * @data: data for the external irq to start up - * - * Multiplex interrupts for irq onto TR2. Clear any pending interrupts and - * unmask irq, both using the appropriate callbacks. - */ -static unsigned int meta_intc_startup_irq(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - void __iomem *vec_addr = meta_intc_vec_addr(hw); - int thread = hard_processor_id(); - - /* Perform any necessary acking. */ - if (data->chip->irq_ack) - data->chip->irq_ack(data); - - /* Wire up this interrupt to the core with HWVECxEXT. */ - metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr); - - /* Perform any necessary unmasking. */ - data->chip->irq_unmask(data); - - return 0; -} - -/** - * meta_intc_shutdown_irq() - turn off an external irq - * @data: data for the external irq to turn off - * - * Mask irq using the appropriate callback and stop muxing it onto TR2. - */ -static void meta_intc_shutdown_irq(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - void __iomem *vec_addr = meta_intc_vec_addr(hw); - - /* Mask the IRQ */ - data->chip->irq_mask(data); - - /* - * Disable the IRQ at the core by removing the interrupt from - * the HW vector mapping. - */ - metag_out32(0, vec_addr); -} - -/** - * meta_intc_ack_irq() - acknowledge an external irq - * @data: data for the external irq to ack - * - * Clear down an edge interrupt in the status register. - */ -static void meta_intc_ack_irq(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - unsigned int bit = 1 << meta_intc_offset(hw); - void __iomem *stat_addr = meta_intc_stat_addr(hw); - - /* Ack the int, if it is still 'on'. - * NOTE - this only works for edge triggered interrupts. - */ - if (metag_in32(stat_addr) & bit) - metag_out32(bit, stat_addr); -} - -/** - * record_irq_is_masked() - record the IRQ masked so it doesn't get handled - * @data: data for the external irq to record - * - * This should get called whenever an external IRQ is masked (by whichever - * callback is used). It records the IRQ masked so that it doesn't get handled - * if it still shows up in the status register. - */ -static void record_irq_is_masked(struct irq_data *data) -{ - struct meta_intc_priv *priv = &meta_intc_priv; - irq_hw_number_t hw = data->hwirq; - - clear_bit(meta_intc_offset(hw), &priv->unmasked[meta_intc_bank(hw)]); -} - -/** - * record_irq_is_unmasked() - record the IRQ unmasked so it can be handled - * @data: data for the external irq to record - * - * This should get called whenever an external IRQ is unmasked (by whichever - * callback is used). It records the IRQ unmasked so that it gets handled if it - * shows up in the status register. - */ -static void record_irq_is_unmasked(struct irq_data *data) -{ - struct meta_intc_priv *priv = &meta_intc_priv; - irq_hw_number_t hw = data->hwirq; - - set_bit(meta_intc_offset(hw), &priv->unmasked[meta_intc_bank(hw)]); -} - -/* - * For use by wrapper IRQ drivers - */ - -/** - * meta_intc_mask_irq_simple() - minimal mask used by wrapper IRQ drivers - * @data: data for the external irq being masked - * - * This should be called by any wrapper IRQ driver mask functions. it doesn't do - * any masking but records the IRQ as masked so that the core code knows the - * mask has taken place. It is the callers responsibility to ensure that the IRQ - * won't trigger an interrupt to the core. - */ -void meta_intc_mask_irq_simple(struct irq_data *data) -{ - record_irq_is_masked(data); -} - -/** - * meta_intc_unmask_irq_simple() - minimal unmask used by wrapper IRQ drivers - * @data: data for the external irq being unmasked - * - * This should be called by any wrapper IRQ driver unmask functions. it doesn't - * do any unmasking but records the IRQ as unmasked so that the core code knows - * the unmask has taken place. It is the callers responsibility to ensure that - * the IRQ can now trigger an interrupt to the core. - */ -void meta_intc_unmask_irq_simple(struct irq_data *data) -{ - record_irq_is_unmasked(data); -} - - -/** - * meta_intc_mask_irq() - mask an external irq using HWMASKEXT - * @data: data for the external irq to mask - * - * This is a default implementation of a mask function which makes use of the - * HWMASKEXT registers available in newer versions. - * - * Earlier versions without these registers should use SoC level IRQ masking - * which call the meta_intc_*_simple() functions above, or if that isn't - * available should use the fallback meta_intc_*_nomask() functions below. - */ -static void meta_intc_mask_irq(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - unsigned int bit = 1 << meta_intc_offset(hw); - void __iomem *mask_addr = meta_intc_mask_addr(hw); - unsigned long flags; - - record_irq_is_masked(data); - - /* update the interrupt mask */ - __global_lock2(flags); - metag_out32(metag_in32(mask_addr) & ~bit, mask_addr); - __global_unlock2(flags); -} - -/** - * meta_intc_unmask_irq() - unmask an external irq using HWMASKEXT - * @data: data for the external irq to unmask - * - * This is a default implementation of an unmask function which makes use of the - * HWMASKEXT registers available on new versions. It should be paired with - * meta_intc_mask_irq() above. - */ -static void meta_intc_unmask_irq(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - unsigned int bit = 1 << meta_intc_offset(hw); - void __iomem *mask_addr = meta_intc_mask_addr(hw); - unsigned long flags; - - record_irq_is_unmasked(data); - - /* update the interrupt mask */ - __global_lock2(flags); - metag_out32(metag_in32(mask_addr) | bit, mask_addr); - __global_unlock2(flags); -} - -/** - * meta_intc_mask_irq_nomask() - mask an external irq by unvectoring - * @data: data for the external irq to mask - * - * This is the version of the mask function for older versions which don't have - * HWMASKEXT registers, or a SoC level means of masking IRQs. Instead the IRQ is - * unvectored from the core and retriggered if necessary later. - */ -static void meta_intc_mask_irq_nomask(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - void __iomem *vec_addr = meta_intc_vec_addr(hw); - - record_irq_is_masked(data); - - /* there is no interrupt mask, so unvector the interrupt */ - metag_out32(0, vec_addr); -} - -/** - * meta_intc_unmask_edge_irq_nomask() - unmask an edge irq by revectoring - * @data: data for the external irq to unmask - * - * This is the version of the unmask function for older versions which don't - * have HWMASKEXT registers, or a SoC level means of masking IRQs. Instead the - * IRQ is revectored back to the core and retriggered if necessary. - * - * The retriggering done by this function is specific to edge interrupts. - */ -static void meta_intc_unmask_edge_irq_nomask(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - unsigned int bit = 1 << meta_intc_offset(hw); - void __iomem *stat_addr = meta_intc_stat_addr(hw); - void __iomem *vec_addr = meta_intc_vec_addr(hw); - unsigned int thread = hard_processor_id(); - - record_irq_is_unmasked(data); - - /* there is no interrupt mask, so revector the interrupt */ - metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr); - - /* - * Re-trigger interrupt - * - * Writing a 1 toggles, and a 0->1 transition triggers. We only - * retrigger if the status bit is already set, which means we - * need to clear it first. Retriggering is fundamentally racy - * because if the interrupt fires again after we clear it we - * could end up clearing it again and the interrupt handler - * thinking it hasn't fired. Therefore we need to keep trying to - * retrigger until the bit is set. - */ - if (metag_in32(stat_addr) & bit) { - metag_out32(bit, stat_addr); - while (!(metag_in32(stat_addr) & bit)) - metag_out32(bit, stat_addr); - } -} - -/** - * meta_intc_unmask_level_irq_nomask() - unmask a level irq by revectoring - * @data: data for the external irq to unmask - * - * This is the version of the unmask function for older versions which don't - * have HWMASKEXT registers, or a SoC level means of masking IRQs. Instead the - * IRQ is revectored back to the core and retriggered if necessary. - * - * The retriggering done by this function is specific to level interrupts. - */ -static void meta_intc_unmask_level_irq_nomask(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - unsigned int bit = 1 << meta_intc_offset(hw); - void __iomem *stat_addr = meta_intc_stat_addr(hw); - void __iomem *vec_addr = meta_intc_vec_addr(hw); - unsigned int thread = hard_processor_id(); - - record_irq_is_unmasked(data); - - /* there is no interrupt mask, so revector the interrupt */ - metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr); - - /* Re-trigger interrupt */ - /* Writing a 1 triggers interrupt */ - if (metag_in32(stat_addr) & bit) - metag_out32(bit, stat_addr); -} - -/** - * meta_intc_irq_set_type() - set the type of an external irq - * @data: data for the external irq to set the type of - * @flow_type: new irq flow type - * - * Set the flow type of an external interrupt. This updates the irq chip and irq - * handler depending on whether the irq is edge or level sensitive (the polarity - * is ignored), and also sets up the bit in HWLEVELEXT so the hardware knows - * when to trigger. - */ -static int meta_intc_irq_set_type(struct irq_data *data, unsigned int flow_type) -{ -#ifdef CONFIG_METAG_SUSPEND_MEM - struct meta_intc_priv *priv = &meta_intc_priv; -#endif - irq_hw_number_t hw = data->hwirq; - unsigned int bit = 1 << meta_intc_offset(hw); - void __iomem *level_addr = meta_intc_level_addr(hw); - unsigned long flags; - unsigned int level; - - /* update the chip/handler */ - if (flow_type & IRQ_TYPE_LEVEL_MASK) - irq_set_chip_handler_name_locked(data, &meta_intc_level_chip, - handle_level_irq, NULL); - else - irq_set_chip_handler_name_locked(data, &meta_intc_edge_chip, - handle_edge_irq, NULL); - - /* and clear/set the bit in HWLEVELEXT */ - __global_lock2(flags); - level = metag_in32(level_addr); - if (flow_type & IRQ_TYPE_LEVEL_MASK) - level |= bit; - else - level &= ~bit; - metag_out32(level, level_addr); -#ifdef CONFIG_METAG_SUSPEND_MEM - priv->levels_altered[meta_intc_bank(hw)] |= bit; -#endif - __global_unlock2(flags); - - return 0; -} - -/** - * meta_intc_irq_demux() - external irq de-multiplexer - * @desc: the interrupt description structure for this irq - * - * The cpu receives an interrupt on TR2 when a SoC interrupt has occurred. It is - * this function's job to demux this irq and figure out exactly which external - * irq needs servicing. - * - * Whilst using TR2 to detect external interrupts is a software convention it is - * (hopefully) unlikely to change. - */ -static void meta_intc_irq_demux(struct irq_desc *desc) -{ - struct meta_intc_priv *priv = &meta_intc_priv; - irq_hw_number_t hw; - unsigned int bank, irq_no, status; - void __iomem *stat_addr = meta_intc_stat_addr(0); - - /* - * Locate which interrupt has caused our handler to run. - */ - for (bank = 0; bank < priv->nr_banks; ++bank) { - /* Which interrupts are currently pending in this bank? */ -recalculate: - status = metag_in32(stat_addr) & priv->unmasked[bank]; - - for (hw = bank*32; status; status >>= 1, ++hw) { - if (status & 0x1) { - /* - * Map the hardware IRQ number to a virtual - * Linux IRQ number. - */ - irq_no = irq_linear_revmap(priv->domain, hw); - - /* - * Only fire off external interrupts that are - * registered to be handled by the kernel. - * Other external interrupts are probably being - * handled by other Meta hardware threads. - */ - generic_handle_irq(irq_no); - - /* - * The handler may have re-enabled interrupts - * which could have caused a nested invocation - * of this code and make the copy of the - * status register we are using invalid. - */ - goto recalculate; - } - } - stat_addr += HWSTAT_STRIDE; - } -} - -#ifdef CONFIG_SMP -/** - * meta_intc_set_affinity() - set the affinity for an interrupt - * @data: data for the external irq to set the affinity of - * @cpumask: cpu mask representing cpus which can handle the interrupt - * @force: whether to force (ignored) - * - * Revector the specified external irq onto a specific cpu's TR2 trigger, so - * that that cpu tends to be the one who handles it. - */ -static int meta_intc_set_affinity(struct irq_data *data, - const struct cpumask *cpumask, bool force) -{ - irq_hw_number_t hw = data->hwirq; - void __iomem *vec_addr = meta_intc_vec_addr(hw); - unsigned int cpu, thread; - - /* - * Wire up this interrupt from HWVECxEXT to the Meta core. - * - * Note that we can't wire up HWVECxEXT to interrupt more than - * one cpu (the interrupt code doesn't support it), so we just - * pick the first cpu we find in 'cpumask'. - */ - cpu = cpumask_any_and(cpumask, cpu_online_mask); - thread = cpu_2_hwthread_id[cpu]; - - metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR2(thread)), vec_addr); - - irq_data_update_effective_affinity(data, cpumask_of(cpu)); - - return 0; -} -#else -#define meta_intc_set_affinity NULL -#endif - -#ifdef CONFIG_PM_SLEEP -#define META_INTC_CHIP_FLAGS (IRQCHIP_MASK_ON_SUSPEND \ - | IRQCHIP_SKIP_SET_WAKE) -#else -#define META_INTC_CHIP_FLAGS 0 -#endif - -/* public edge/level irq chips which SoCs can override */ - -struct irq_chip meta_intc_edge_chip = { - .irq_startup = meta_intc_startup_irq, - .irq_shutdown = meta_intc_shutdown_irq, - .irq_ack = meta_intc_ack_irq, - .irq_mask = meta_intc_mask_irq, - .irq_unmask = meta_intc_unmask_irq, - .irq_set_type = meta_intc_irq_set_type, - .irq_set_affinity = meta_intc_set_affinity, - .flags = META_INTC_CHIP_FLAGS, -}; - -struct irq_chip meta_intc_level_chip = { - .irq_startup = meta_intc_startup_irq, - .irq_shutdown = meta_intc_shutdown_irq, - .irq_set_type = meta_intc_irq_set_type, - .irq_mask = meta_intc_mask_irq, - .irq_unmask = meta_intc_unmask_irq, - .irq_set_affinity = meta_intc_set_affinity, - .flags = META_INTC_CHIP_FLAGS, -}; - -/** - * meta_intc_map() - map an external irq - * @d: irq domain of external trigger block - * @irq: virtual irq number - * @hw: hardware irq number within external trigger block - * - * This sets up a virtual irq for a specified hardware interrupt. The irq chip - * and handler is configured, using the HWLEVELEXT registers to determine - * edge/level flow type. These registers will have been set when the irq type is - * set (or set to a default at init time). - */ -static int meta_intc_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hw) -{ - unsigned int bit = 1 << meta_intc_offset(hw); - void __iomem *level_addr = meta_intc_level_addr(hw); - - /* Go by the current sense in the HWLEVELEXT register */ - if (metag_in32(level_addr) & bit) - irq_set_chip_and_handler(irq, &meta_intc_level_chip, - handle_level_irq); - else - irq_set_chip_and_handler(irq, &meta_intc_edge_chip, - handle_edge_irq); - - irqd_set_single_target(irq_desc_get_irq_data(irq_to_desc(irq))); - return 0; -} - -static const struct irq_domain_ops meta_intc_domain_ops = { - .map = meta_intc_map, - .xlate = irq_domain_xlate_twocell, -}; - -#ifdef CONFIG_METAG_SUSPEND_MEM - -/** - * struct meta_intc_context - suspend context - * @levels: State of HWLEVELEXT registers - * @masks: State of HWMASKEXT registers - * @vectors: State of HWVECEXT registers - * @txvecint: State of TxVECINT registers - * - * This structure stores the IRQ state across suspend. - */ -struct meta_intc_context { - u32 levels[4]; - u32 masks[4]; - u8 vectors[4*32]; - - u8 txvecint[4][4]; -}; - -/* suspend context */ -static struct meta_intc_context *meta_intc_context; - -/** - * meta_intc_suspend() - store irq state - * - * To avoid interfering with other threads we only save the IRQ state of IRQs in - * use by Linux. - */ -static int meta_intc_suspend(void) -{ - struct meta_intc_priv *priv = &meta_intc_priv; - int i, j; - irq_hw_number_t hw; - unsigned int bank; - unsigned long flags; - struct meta_intc_context *context; - void __iomem *level_addr, *mask_addr, *vec_addr; - u32 mask, bit; - - context = kzalloc(sizeof(*context), GFP_ATOMIC); - if (!context) - return -ENOMEM; - - hw = 0; - level_addr = meta_intc_level_addr(0); - mask_addr = meta_intc_mask_addr(0); - for (bank = 0; bank < priv->nr_banks; ++bank) { - vec_addr = meta_intc_vec_addr(hw); - - /* create mask of interrupts in use */ - mask = 0; - for (bit = 1; bit; bit <<= 1) { - i = irq_linear_revmap(priv->domain, hw); - /* save mapped irqs which are enabled or have actions */ - if (i && (!irqd_irq_disabled(irq_get_irq_data(i)) || - irq_has_action(i))) { - mask |= bit; - - /* save trigger vector */ - context->vectors[hw] = metag_in32(vec_addr); - } - - ++hw; - vec_addr += HWVECnEXT_STRIDE; - } - - /* save level state if any IRQ levels altered */ - if (priv->levels_altered[bank]) - context->levels[bank] = metag_in32(level_addr); - /* save mask state if any IRQs in use */ - if (mask) - context->masks[bank] = metag_in32(mask_addr); - - level_addr += HWSTAT_STRIDE; - mask_addr += HWSTAT_STRIDE; - } - - /* save trigger matrixing */ - __global_lock2(flags); - for (i = 0; i < 4; ++i) - for (j = 0; j < 4; ++j) - context->txvecint[i][j] = metag_in32(T0VECINT_BHALT + - TnVECINT_STRIDE*i + - 8*j); - __global_unlock2(flags); - - meta_intc_context = context; - return 0; -} - -/** - * meta_intc_resume() - restore saved irq state - * - * Restore the saved IRQ state and drop it. - */ -static void meta_intc_resume(void) -{ - struct meta_intc_priv *priv = &meta_intc_priv; - int i, j; - irq_hw_number_t hw; - unsigned int bank; - unsigned long flags; - struct meta_intc_context *context = meta_intc_context; - void __iomem *level_addr, *mask_addr, *vec_addr; - u32 mask, bit, tmp; - - meta_intc_context = NULL; - - hw = 0; - level_addr = meta_intc_level_addr(0); - mask_addr = meta_intc_mask_addr(0); - for (bank = 0; bank < priv->nr_banks; ++bank) { - vec_addr = meta_intc_vec_addr(hw); - - /* create mask of interrupts in use */ - mask = 0; - for (bit = 1; bit; bit <<= 1) { - i = irq_linear_revmap(priv->domain, hw); - /* restore mapped irqs, enabled or with actions */ - if (i && (!irqd_irq_disabled(irq_get_irq_data(i)) || - irq_has_action(i))) { - mask |= bit; - - /* restore trigger vector */ - metag_out32(context->vectors[hw], vec_addr); - } - - ++hw; - vec_addr += HWVECnEXT_STRIDE; - } - - if (mask) { - /* restore mask state */ - __global_lock2(flags); - tmp = metag_in32(mask_addr); - tmp = (tmp & ~mask) | (context->masks[bank] & mask); - metag_out32(tmp, mask_addr); - __global_unlock2(flags); - } - - mask = priv->levels_altered[bank]; - if (mask) { - /* restore level state */ - __global_lock2(flags); - tmp = metag_in32(level_addr); - tmp = (tmp & ~mask) | (context->levels[bank] & mask); - metag_out32(tmp, level_addr); - __global_unlock2(flags); - } - - level_addr += HWSTAT_STRIDE; - mask_addr += HWSTAT_STRIDE; - } - - /* restore trigger matrixing */ - __global_lock2(flags); - for (i = 0; i < 4; ++i) { - for (j = 0; j < 4; ++j) { - metag_out32(context->txvecint[i][j], - T0VECINT_BHALT + - TnVECINT_STRIDE*i + - 8*j); - } - } - __global_unlock2(flags); - - kfree(context); -} - -static struct syscore_ops meta_intc_syscore_ops = { - .suspend = meta_intc_suspend, - .resume = meta_intc_resume, -}; - -static void __init meta_intc_init_syscore_ops(struct meta_intc_priv *priv) -{ - register_syscore_ops(&meta_intc_syscore_ops); -} -#else -#define meta_intc_init_syscore_ops(priv) do {} while (0) -#endif - -/** - * meta_intc_init_cpu() - register with a Meta cpu - * @priv: private interrupt controller data - * @cpu: the CPU to register on - * - * Configure @cpu's TR2 irq so that we can demux external irqs. - */ -static void __init meta_intc_init_cpu(struct meta_intc_priv *priv, int cpu) -{ - unsigned int thread = cpu_2_hwthread_id[cpu]; - unsigned int signum = TBID_SIGNUM_TR2(thread); - int irq = tbisig_map(signum); - - /* Register the multiplexed IRQ handler */ - irq_set_chained_handler(irq, meta_intc_irq_demux); - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); -} - -/** - * meta_intc_no_mask() - indicate lack of HWMASKEXT registers - * - * Called from SoC code (or init code below) to dynamically indicate the lack of - * HWMASKEXT registers (for example depending on some SoC revision register). - * This alters the irq mask and unmask callbacks to use the fallback - * unvectoring/retriggering technique instead of using HWMASKEXT registers. - */ -void __init meta_intc_no_mask(void) -{ - meta_intc_edge_chip.irq_mask = meta_intc_mask_irq_nomask; - meta_intc_edge_chip.irq_unmask = meta_intc_unmask_edge_irq_nomask; - meta_intc_level_chip.irq_mask = meta_intc_mask_irq_nomask; - meta_intc_level_chip.irq_unmask = meta_intc_unmask_level_irq_nomask; -} - -/** - * init_external_IRQ() - initialise the external irq controller - * - * Set up the external irq controller using device tree properties. This is - * called from init_IRQ(). - */ -int __init init_external_IRQ(void) -{ - struct meta_intc_priv *priv = &meta_intc_priv; - struct device_node *node; - int ret, cpu; - u32 val; - bool no_masks = false; - - node = of_find_compatible_node(NULL, NULL, "img,meta-intc"); - if (!node) - return -ENOENT; - - /* Get number of banks */ - ret = of_property_read_u32(node, "num-banks", &val); - if (ret) { - pr_err("meta-intc: No num-banks property found\n"); - return ret; - } - if (val < 1 || val > 4) { - pr_err("meta-intc: num-banks (%u) out of range\n", val); - return -EINVAL; - } - priv->nr_banks = val; - - /* Are any mask registers present? */ - if (of_get_property(node, "no-mask", NULL)) - no_masks = true; - - /* No HWMASKEXT registers present? */ - if (no_masks) - meta_intc_no_mask(); - - /* Set up an IRQ domain */ - /* - * This is a legacy IRQ domain for now until all the platform setup code - * has been converted to devicetree. - */ - priv->domain = irq_domain_add_linear(node, priv->nr_banks*32, - &meta_intc_domain_ops, priv); - if (unlikely(!priv->domain)) { - pr_err("meta-intc: cannot add IRQ domain\n"); - return -ENOMEM; - } - - /* Setup TR2 for all cpus. */ - for_each_possible_cpu(cpu) - meta_intc_init_cpu(priv, cpu); - - /* Set up system suspend/resume callbacks */ - meta_intc_init_syscore_ops(priv); - - pr_info("meta-intc: External IRQ controller initialised (%u IRQs)\n", - priv->nr_banks*32); - - return 0; -} diff --git a/drivers/irqchip/irq-metag.c b/drivers/irqchip/irq-metag.c deleted file mode 100644 index 857b946747eb..000000000000 --- a/drivers/irqchip/irq-metag.c +++ /dev/null @@ -1,343 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * Meta internal (HWSTATMETA) interrupt code. - * - * Copyright (C) 2011-2012 Imagination Technologies Ltd. - * - * This code is based on the code in SoC/common/irq.c and SoC/comet/irq.c - * The code base could be generalised/merged as a lot of the functionality is - * similar. Until this is done, we try to keep the code simple here. - */ - -#include -#include -#include - -#include -#include - -#define PERF0VECINT 0x04820580 -#define PERF1VECINT 0x04820588 -#define PERF0TRIG_OFFSET 16 -#define PERF1TRIG_OFFSET 17 - -/** - * struct metag_internal_irq_priv - private meta internal interrupt data - * @domain: IRQ domain for all internal Meta IRQs (HWSTATMETA) - * @unmasked: Record of unmasked IRQs - */ -struct metag_internal_irq_priv { - struct irq_domain *domain; - - unsigned long unmasked; -}; - -/* Private data for the one and only internal interrupt controller */ -static struct metag_internal_irq_priv metag_internal_irq_priv; - -static unsigned int metag_internal_irq_startup(struct irq_data *data); -static void metag_internal_irq_shutdown(struct irq_data *data); -static void metag_internal_irq_ack(struct irq_data *data); -static void metag_internal_irq_mask(struct irq_data *data); -static void metag_internal_irq_unmask(struct irq_data *data); -#ifdef CONFIG_SMP -static int metag_internal_irq_set_affinity(struct irq_data *data, - const struct cpumask *cpumask, bool force); -#endif - -static struct irq_chip internal_irq_edge_chip = { - .name = "HWSTATMETA-IRQ", - .irq_startup = metag_internal_irq_startup, - .irq_shutdown = metag_internal_irq_shutdown, - .irq_ack = metag_internal_irq_ack, - .irq_mask = metag_internal_irq_mask, - .irq_unmask = metag_internal_irq_unmask, -#ifdef CONFIG_SMP - .irq_set_affinity = metag_internal_irq_set_affinity, -#endif -}; - -/* - * metag_hwvec_addr - get the address of *VECINT regs of irq - * - * This function is a table of supported triggers on HWSTATMETA - * Could do with a structure, but better keep it simple. Changes - * in this code should be rare. - */ -static inline void __iomem *metag_hwvec_addr(irq_hw_number_t hw) -{ - void __iomem *addr; - - switch (hw) { - case PERF0TRIG_OFFSET: - addr = (void __iomem *)PERF0VECINT; - break; - case PERF1TRIG_OFFSET: - addr = (void __iomem *)PERF1VECINT; - break; - default: - addr = NULL; - break; - } - return addr; -} - -/* - * metag_internal_startup - setup an internal irq - * @irq: the irq to startup - * - * Multiplex interrupts for @irq onto TR1. Clear any pending - * interrupts. - */ -static unsigned int metag_internal_irq_startup(struct irq_data *data) -{ - /* Clear (toggle) the bit in HWSTATMETA for our interrupt. */ - metag_internal_irq_ack(data); - - /* Enable the interrupt by unmasking it */ - metag_internal_irq_unmask(data); - - return 0; -} - -/* - * metag_internal_irq_shutdown - turn off the irq - * @irq: the irq number to turn off - * - * Mask @irq and clear any pending interrupts. - * Stop muxing @irq onto TR1. - */ -static void metag_internal_irq_shutdown(struct irq_data *data) -{ - /* Disable the IRQ at the core by masking it. */ - metag_internal_irq_mask(data); - - /* Clear (toggle) the bit in HWSTATMETA for our interrupt. */ - metag_internal_irq_ack(data); -} - -/* - * metag_internal_irq_ack - acknowledge irq - * @irq: the irq to ack - */ -static void metag_internal_irq_ack(struct irq_data *data) -{ - irq_hw_number_t hw = data->hwirq; - unsigned int bit = 1 << hw; - - if (metag_in32(HWSTATMETA) & bit) - metag_out32(bit, HWSTATMETA); -} - -/** - * metag_internal_irq_mask() - mask an internal irq by unvectoring - * @data: data for the internal irq to mask - * - * HWSTATMETA has no mask register. Instead the IRQ is unvectored from the core - * and retriggered if necessary later. - */ -static void metag_internal_irq_mask(struct irq_data *data) -{ - struct metag_internal_irq_priv *priv = &metag_internal_irq_priv; - irq_hw_number_t hw = data->hwirq; - void __iomem *vec_addr = metag_hwvec_addr(hw); - - clear_bit(hw, &priv->unmasked); - - /* there is no interrupt mask, so unvector the interrupt */ - metag_out32(0, vec_addr); -} - -/** - * meta_intc_unmask_edge_irq_nomask() - unmask an edge irq by revectoring - * @data: data for the internal irq to unmask - * - * HWSTATMETA has no mask register. Instead the IRQ is revectored back to the - * core and retriggered if necessary. - */ -static void metag_internal_irq_unmask(struct irq_data *data) -{ - struct metag_internal_irq_priv *priv = &metag_internal_irq_priv; - irq_hw_number_t hw = data->hwirq; - unsigned int bit = 1 << hw; - void __iomem *vec_addr = metag_hwvec_addr(hw); - unsigned int thread = hard_processor_id(); - - set_bit(hw, &priv->unmasked); - - /* there is no interrupt mask, so revector the interrupt */ - metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR1(thread)), vec_addr); - - /* - * Re-trigger interrupt - * - * Writing a 1 toggles, and a 0->1 transition triggers. We only - * retrigger if the status bit is already set, which means we - * need to clear it first. Retriggering is fundamentally racy - * because if the interrupt fires again after we clear it we - * could end up clearing it again and the interrupt handler - * thinking it hasn't fired. Therefore we need to keep trying to - * retrigger until the bit is set. - */ - if (metag_in32(HWSTATMETA) & bit) { - metag_out32(bit, HWSTATMETA); - while (!(metag_in32(HWSTATMETA) & bit)) - metag_out32(bit, HWSTATMETA); - } -} - -#ifdef CONFIG_SMP -/* - * metag_internal_irq_set_affinity - set the affinity for an interrupt - */ -static int metag_internal_irq_set_affinity(struct irq_data *data, - const struct cpumask *cpumask, bool force) -{ - unsigned int cpu, thread; - irq_hw_number_t hw = data->hwirq; - /* - * Wire up this interrupt from *VECINT to the Meta core. - * - * Note that we can't wire up *VECINT to interrupt more than - * one cpu (the interrupt code doesn't support it), so we just - * pick the first cpu we find in 'cpumask'. - */ - cpu = cpumask_any_and(cpumask, cpu_online_mask); - thread = cpu_2_hwthread_id[cpu]; - - metag_out32(TBI_TRIG_VEC(TBID_SIGNUM_TR1(thread)), - metag_hwvec_addr(hw)); - - return 0; -} -#endif - -/* - * metag_internal_irq_demux - irq de-multiplexer - * @irq: the interrupt number - * @desc: the interrupt description structure for this irq - * - * The cpu receives an interrupt on TR1 when an interrupt has - * occurred. It is this function's job to demux this irq and - * figure out exactly which trigger needs servicing. - */ -static void metag_internal_irq_demux(struct irq_desc *desc) -{ - struct metag_internal_irq_priv *priv = irq_desc_get_handler_data(desc); - irq_hw_number_t hw; - unsigned int irq_no; - u32 status; - -recalculate: - status = metag_in32(HWSTATMETA) & priv->unmasked; - - for (hw = 0; status != 0; status >>= 1, ++hw) { - if (status & 0x1) { - /* - * Map the hardware IRQ number to a virtual Linux IRQ - * number. - */ - irq_no = irq_linear_revmap(priv->domain, hw); - - /* - * Only fire off interrupts that are - * registered to be handled by the kernel. - * Other interrupts are probably being - * handled by other Meta hardware threads. - */ - generic_handle_irq(irq_no); - - /* - * The handler may have re-enabled interrupts - * which could have caused a nested invocation - * of this code and make the copy of the - * status register we are using invalid. - */ - goto recalculate; - } - } -} - -/** - * internal_irq_map() - Map an internal meta IRQ to a virtual IRQ number. - * @hw: Number of the internal IRQ. Must be in range. - * - * Returns: The virtual IRQ number of the Meta internal IRQ specified by - * @hw. - */ -int internal_irq_map(unsigned int hw) -{ - struct metag_internal_irq_priv *priv = &metag_internal_irq_priv; - if (!priv->domain) - return -ENODEV; - return irq_create_mapping(priv->domain, hw); -} - -/** - * metag_internal_irq_init_cpu - regsister with the Meta cpu - * @cpu: the CPU to register on - * - * Configure @cpu's TR1 irq so that we can demux irqs. - */ -static void metag_internal_irq_init_cpu(struct metag_internal_irq_priv *priv, - int cpu) -{ - unsigned int thread = cpu_2_hwthread_id[cpu]; - unsigned int signum = TBID_SIGNUM_TR1(thread); - int irq = tbisig_map(signum); - - /* Register the multiplexed IRQ handler */ - irq_set_chained_handler_and_data(irq, metag_internal_irq_demux, priv); - irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW); -} - -/** - * metag_internal_intc_map() - map an internal irq - * @d: irq domain of internal trigger block - * @irq: virtual irq number - * @hw: hardware irq number within internal trigger block - * - * This sets up a virtual irq for a specified hardware interrupt. The irq chip - * and handler is configured. - */ -static int metag_internal_intc_map(struct irq_domain *d, unsigned int irq, - irq_hw_number_t hw) -{ - /* only register interrupt if it is mapped */ - if (!metag_hwvec_addr(hw)) - return -EINVAL; - - irq_set_chip_and_handler(irq, &internal_irq_edge_chip, - handle_edge_irq); - return 0; -} - -static const struct irq_domain_ops metag_internal_intc_domain_ops = { - .map = metag_internal_intc_map, -}; - -/** - * metag_internal_irq_register - register internal IRQs - * - * Register the irq chip and handler function for all internal IRQs - */ -int __init init_internal_IRQ(void) -{ - struct metag_internal_irq_priv *priv = &metag_internal_irq_priv; - unsigned int cpu; - - /* Set up an IRQ domain */ - priv->domain = irq_domain_add_linear(NULL, 32, - &metag_internal_intc_domain_ops, - priv); - if (unlikely(!priv->domain)) { - pr_err("meta-internal-intc: cannot add IRQ domain\n"); - return -ENOMEM; - } - - /* Setup TR1 for all cpus. */ - for_each_possible_cpu(cpu) - metag_internal_irq_init_cpu(priv, cpu); - - return 0; -}; -- cgit v1.2.3-59-g8ed1b From b79a732504ad2d6552458eaf72b4ed807da88340 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 21 Feb 2018 15:42:32 +0000 Subject: clocksource: Remove metag generic timer driver Now that arch/metag/ has been removed, remove the metag generic per-thread timer driver. It is of no value without the architecture code. Signed-off-by: James Hogan Acked-by: Daniel Lezcano Cc: Thomas Gleixner Cc: linux-metag@vger.kernel.org --- drivers/clocksource/Kconfig | 5 -- drivers/clocksource/Makefile | 1 - drivers/clocksource/metag_generic.c | 161 ------------------------------------ include/clocksource/metag_generic.h | 21 ----- include/linux/cpuhotplug.h | 1 - 5 files changed, 189 deletions(-) delete mode 100644 drivers/clocksource/metag_generic.c delete mode 100644 include/clocksource/metag_generic.h (limited to 'drivers') diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index b3b4ed9b6874..f99dbc2f7ee4 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -391,11 +391,6 @@ config ATMEL_ST help Support for the Atmel ST timer. -config CLKSRC_METAG_GENERIC - def_bool y if METAG - help - This option enables support for the Meta per-thread timers. - config CLKSRC_EXYNOS_MCT bool "Exynos multi core timer driver" if COMPILE_TEST depends on ARM || ARM64 diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index d6dec4489d66..a2d47e9ecf91 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -61,7 +61,6 @@ obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o obj-$(CONFIG_ARM_GLOBAL_TIMER) += arm_global_timer.o obj-$(CONFIG_ARMV7M_SYSTICK) += armv7m_systick.o obj-$(CONFIG_ARM_TIMER_SP804) += timer-sp804.o -obj-$(CONFIG_CLKSRC_METAG_GENERIC) += metag_generic.o obj-$(CONFIG_ARCH_HAS_TICK_BROADCAST) += dummy_timer.o obj-$(CONFIG_KEYSTONE_TIMER) += timer-keystone.o obj-$(CONFIG_INTEGRATOR_AP_TIMER) += timer-integrator-ap.o diff --git a/drivers/clocksource/metag_generic.c b/drivers/clocksource/metag_generic.c deleted file mode 100644 index 3e5fa2f62d5f..000000000000 --- a/drivers/clocksource/metag_generic.c +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright (C) 2005-2013 Imagination Technologies Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - * - * Support for Meta per-thread timers. - * - * Meta hardware threads have 2 timers. The background timer (TXTIMER) is used - * as a free-running time base (hz clocksource), and the interrupt timer - * (TXTIMERI) is used for the timer interrupt (clock event). Both counters - * traditionally count at approximately 1MHz. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#define HARDWARE_FREQ 1000000 /* 1MHz */ -#define HARDWARE_DIV 1 /* divide by 1 = 1MHz clock */ -#define HARDWARE_TO_NS_SHIFT 10 /* convert ticks to ns */ - -static unsigned int hwtimer_freq = HARDWARE_FREQ; -static DEFINE_PER_CPU(struct clock_event_device, local_clockevent); -static DEFINE_PER_CPU(char [11], local_clockevent_name); - -static int metag_timer_set_next_event(unsigned long delta, - struct clock_event_device *dev) -{ - __core_reg_set(TXTIMERI, -delta); - return 0; -} - -static u64 metag_clocksource_read(struct clocksource *cs) -{ - return __core_reg_get(TXTIMER); -} - -static struct clocksource clocksource_metag = { - .name = "META", - .rating = 200, - .mask = CLOCKSOURCE_MASK(32), - .read = metag_clocksource_read, - .flags = CLOCK_SOURCE_IS_CONTINUOUS, -}; - -static irqreturn_t metag_timer_interrupt(int irq, void *dummy) -{ - struct clock_event_device *evt = this_cpu_ptr(&local_clockevent); - - evt->event_handler(evt); - - return IRQ_HANDLED; -} - -static struct irqaction metag_timer_irq = { - .name = "META core timer", - .handler = metag_timer_interrupt, - .flags = IRQF_TIMER | IRQF_IRQPOLL | IRQF_PERCPU, -}; - -unsigned long long sched_clock(void) -{ - unsigned long long ticks = __core_reg_get(TXTIMER); - return ticks << HARDWARE_TO_NS_SHIFT; -} - -static int arch_timer_starting_cpu(unsigned int cpu) -{ - unsigned int txdivtime; - struct clock_event_device *clk = &per_cpu(local_clockevent, cpu); - char *name = per_cpu(local_clockevent_name, cpu); - - txdivtime = __core_reg_get(TXDIVTIME); - - txdivtime &= ~TXDIVTIME_DIV_BITS; - txdivtime |= (HARDWARE_DIV & TXDIVTIME_DIV_BITS); - - __core_reg_set(TXDIVTIME, txdivtime); - - sprintf(name, "META %d", cpu); - clk->name = name; - clk->features = CLOCK_EVT_FEAT_ONESHOT, - - clk->rating = 200, - clk->shift = 12, - clk->irq = tbisig_map(TBID_SIGNUM_TRT), - clk->set_next_event = metag_timer_set_next_event, - - clk->mult = div_sc(hwtimer_freq, NSEC_PER_SEC, clk->shift); - clk->max_delta_ns = clockevent_delta2ns(0x7fffffff, clk); - clk->max_delta_ticks = 0x7fffffff; - clk->min_delta_ns = clockevent_delta2ns(0xf, clk); - clk->min_delta_ticks = 0xf; - clk->cpumask = cpumask_of(cpu); - - clockevents_register_device(clk); - - /* - * For all non-boot CPUs we need to synchronize our free - * running clock (TXTIMER) with the boot CPU's clock. - * - * While this won't be accurate, it should be close enough. - */ - if (cpu) { - unsigned int thread0 = cpu_2_hwthread_id[0]; - unsigned long val; - - val = core_reg_read(TXUCT_ID, TXTIMER_REGNUM, thread0); - __core_reg_set(TXTIMER, val); - } - return 0; -} - -int __init metag_generic_timer_init(void) -{ - /* - * On Meta 2 SoCs, the actual frequency of the timer is based on the - * Meta core clock speed divided by an integer, so it is only - * approximately 1MHz. Calculating the real frequency here drastically - * reduces clock skew on these SoCs. - */ -#ifdef CONFIG_METAG_META21 - hwtimer_freq = get_coreclock() / (metag_in32(EXPAND_TIMER_DIV) + 1); -#endif - pr_info("Timer frequency: %u Hz\n", hwtimer_freq); - - clocksource_register_hz(&clocksource_metag, hwtimer_freq); - - setup_irq(tbisig_map(TBID_SIGNUM_TRT), &metag_timer_irq); - - /* Hook cpu boot to configure the CPU's timers */ - return cpuhp_setup_state(CPUHP_AP_METAG_TIMER_STARTING, - "clockevents/metag:starting", - arch_timer_starting_cpu, NULL); -} diff --git a/include/clocksource/metag_generic.h b/include/clocksource/metag_generic.h deleted file mode 100644 index ac17e7d06cfb..000000000000 --- a/include/clocksource/metag_generic.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (C) 2013 Imaginaton Technologies Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ -#ifndef __CLKSOURCE_METAG_GENERIC_H -#define __CLKSOURCE_METAG_GENERIC_H - -extern int metag_generic_timer_init(void); - -#endif /* __CLKSOURCE_METAG_GENERIC_H */ diff --git a/include/linux/cpuhotplug.h b/include/linux/cpuhotplug.h index c7a950681f3a..5b211fe295f0 100644 --- a/include/linux/cpuhotplug.h +++ b/include/linux/cpuhotplug.h @@ -121,7 +121,6 @@ enum cpuhp_state { CPUHP_AP_JCORE_TIMER_STARTING, CPUHP_AP_EXYNOS4_MCT_TIMER_STARTING, CPUHP_AP_ARM_TWD_STARTING, - CPUHP_AP_METAG_TIMER_STARTING, CPUHP_AP_QCOM_TIMER_STARTING, CPUHP_AP_ARMADA_TIMER_STARTING, CPUHP_AP_MARCO_TIMER_STARTING, -- cgit v1.2.3-59-g8ed1b From 5ba484e79f1370fda5e43cd0da1f2a2a59895e81 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 21 Feb 2018 15:37:54 +0000 Subject: tty: Remove metag DA TTY and console driver Now that arch/metag/ has been removed, remove the metag DA TTY and console driver. It is of no value without the architecture code. Signed-off-by: James Hogan Acked-by: Greg Kroah-Hartman Cc: Jiri Slaby Cc: linux-metag@vger.kernel.org --- drivers/tty/Kconfig | 13 - drivers/tty/Makefile | 1 - drivers/tty/metag_da.c | 665 ------------------------------------------------- 3 files changed, 679 deletions(-) delete mode 100644 drivers/tty/metag_da.c (limited to 'drivers') diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig index b811442c5ce6..75a71ebcb369 100644 --- a/drivers/tty/Kconfig +++ b/drivers/tty/Kconfig @@ -402,19 +402,6 @@ config GOLDFISH_TTY_EARLY_CONSOLE default y if GOLDFISH_TTY=y select SERIAL_EARLYCON -config DA_TTY - bool "DA TTY" - depends on METAG_DA - select SERIAL_NONSTANDARD - help - This enables a TTY on a Dash channel. - -config DA_CONSOLE - bool "DA Console" - depends on DA_TTY - help - This enables a console on a Dash channel. - config MIPS_EJTAG_FDC_TTY bool "MIPS EJTAG Fast Debug Channel TTY" depends on MIPS_CDMM diff --git a/drivers/tty/Makefile b/drivers/tty/Makefile index 8ce3a8661b31..47c71f43a397 100644 --- a/drivers/tty/Makefile +++ b/drivers/tty/Makefile @@ -32,7 +32,6 @@ obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o obj-$(CONFIG_SYNCLINK) += synclink.o obj-$(CONFIG_PPC_EPAPR_HV_BYTECHAN) += ehv_bytechan.o obj-$(CONFIG_GOLDFISH_TTY) += goldfish.o -obj-$(CONFIG_DA_TTY) += metag_da.o obj-$(CONFIG_MIPS_EJTAG_FDC_TTY) += mips_ejtag_fdc.o obj-$(CONFIG_VCC) += vcc.o diff --git a/drivers/tty/metag_da.c b/drivers/tty/metag_da.c deleted file mode 100644 index 99eaed4b2dbc..000000000000 --- a/drivers/tty/metag_da.c +++ /dev/null @@ -1,665 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * dashtty.c - tty driver for Dash channels interface. - * - * Copyright (C) 2007,2008,2012 Imagination Technologies - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/* Channel error codes */ -#define CONAOK 0 -#define CONERR 1 -#define CONBAD 2 -#define CONPRM 3 -#define CONADR 4 -#define CONCNT 5 -#define CONCBF 6 -#define CONCBE 7 -#define CONBSY 8 - -/* Default channel for the console */ -#define CONSOLE_CHANNEL 1 - -#define NUM_TTY_CHANNELS 6 - -/* Auto allocate */ -#define DA_TTY_MAJOR 0 - -/* A speedy poll rate helps the userland debug process connection response. - * But, if you set it too high then no other userland processes get much - * of a look in. - */ -#define DA_TTY_POLL (HZ / 50) - -/* - * A short put delay improves latency but has a high throughput overhead - */ -#define DA_TTY_PUT_DELAY (HZ / 100) - -static atomic_t num_channels_need_poll = ATOMIC_INIT(0); - -static struct timer_list poll_timer; - -static struct tty_driver *channel_driver; - -static struct timer_list put_timer; -static struct task_struct *dashtty_thread; - -/* - * The console_poll parameter determines whether the console channel should be - * polled for input. - * By default the console channel isn't polled at all, in order to avoid the - * overhead, but that means it isn't possible to have a login on /dev/console. - */ -static bool console_poll; -module_param(console_poll, bool, S_IRUGO); - -#define RX_BUF_SIZE 1024 - -enum { - INCHR = 1, - OUTCHR, - RDBUF, - WRBUF, - RDSTAT -}; - -/** - * struct dashtty_port - Wrapper struct for dashtty tty_port. - * @port: TTY port data - * @rx_lock: Lock for rx_buf. - * This protects between the poll timer and user context. - * It's also held during read SWITCH operations. - * @rx_buf: Read buffer - * @xmit_lock: Lock for xmit_*, and port.xmit_buf. - * This protects between user context and kernel thread. - * It's also held during write SWITCH operations. - * @xmit_cnt: Size of xmit buffer contents - * @xmit_head: Head of xmit buffer where data is written - * @xmit_tail: Tail of xmit buffer where data is read - * @xmit_empty: Completion for xmit buffer being empty - */ -struct dashtty_port { - struct tty_port port; - spinlock_t rx_lock; - void *rx_buf; - struct mutex xmit_lock; - unsigned int xmit_cnt; - unsigned int xmit_head; - unsigned int xmit_tail; - struct completion xmit_empty; -}; - -static struct dashtty_port dashtty_ports[NUM_TTY_CHANNELS]; - -static atomic_t dashtty_xmit_cnt = ATOMIC_INIT(0); -static wait_queue_head_t dashtty_waitqueue; - -/* - * Low-level DA channel access routines - */ -static int chancall(int in_bios_function, int in_channel, - int in_arg2, void *in_arg3, - void *in_arg4) -{ - register int bios_function asm("D1Ar1") = in_bios_function; - register int channel asm("D0Ar2") = in_channel; - register int arg2 asm("D1Ar3") = in_arg2; - register void *arg3 asm("D0Ar4") = in_arg3; - register void *arg4 asm("D1Ar5") = in_arg4; - register int bios_call asm("D0Ar6") = 3; - register int result asm("D0Re0"); - - asm volatile ( - "MSETL [A0StP++], %6,%4,%2\n\t" - "ADD A0StP, A0StP, #8\n\t" - "SWITCH #0x0C30208\n\t" - "GETD %0, [A0StP+#-8]\n\t" - "SUB A0StP, A0StP, #(4*6)+8\n\t" - : "=d" (result) /* outs */ - : "d" (bios_function), - "d" (channel), - "d" (arg2), - "d" (arg3), - "d" (arg4), - "d" (bios_call) /* ins */ - : "memory"); - - return result; -} - -/* - * Attempts to fetch count bytes from channel and returns actual count. - */ -static int fetch_data(unsigned int channel) -{ - struct dashtty_port *dport = &dashtty_ports[channel]; - int received = 0; - - spin_lock_bh(&dport->rx_lock); - /* check the port isn't being shut down */ - if (!dport->rx_buf) - goto unlock; - if (chancall(RDBUF, channel, RX_BUF_SIZE, - (void *)dport->rx_buf, &received) == CONAOK) { - if (received) { - int space; - unsigned char *cbuf; - - space = tty_prepare_flip_string(&dport->port, &cbuf, - received); - - if (space <= 0) - goto unlock; - - memcpy(cbuf, dport->rx_buf, space); - tty_flip_buffer_push(&dport->port); - } - } -unlock: - spin_unlock_bh(&dport->rx_lock); - - return received; -} - -/** - * find_channel_to_poll() - Returns number of the next channel to poll. - * Returns: The number of the next channel to poll, or -1 if none need - * polling. - */ -static int find_channel_to_poll(void) -{ - static int last_polled_channel; - int last = last_polled_channel; - int chan; - struct dashtty_port *dport; - - for (chan = last + 1; ; ++chan) { - if (chan >= NUM_TTY_CHANNELS) - chan = 0; - - dport = &dashtty_ports[chan]; - if (dport->rx_buf) { - last_polled_channel = chan; - return chan; - } - - if (chan == last) - break; - } - return -1; -} - -/** - * put_channel_data() - Write out a block of channel data. - * @chan: DA channel number. - * - * Write a single block of data out to the debug adapter. If the circular buffer - * is wrapped then only the first block is written. - * - * Returns: 1 if the remote buffer was too full to accept data. - * 0 otherwise. - */ -static int put_channel_data(unsigned int chan) -{ - struct dashtty_port *dport; - struct tty_struct *tty; - int number_written; - unsigned int count = 0; - - dport = &dashtty_ports[chan]; - mutex_lock(&dport->xmit_lock); - if (dport->xmit_cnt) { - count = min((unsigned int)(SERIAL_XMIT_SIZE - dport->xmit_tail), - dport->xmit_cnt); - chancall(WRBUF, chan, count, - dport->port.xmit_buf + dport->xmit_tail, - &number_written); - dport->xmit_cnt -= number_written; - if (!dport->xmit_cnt) { - /* reset pointers to avoid wraps */ - dport->xmit_head = 0; - dport->xmit_tail = 0; - complete(&dport->xmit_empty); - } else { - dport->xmit_tail += number_written; - if (dport->xmit_tail >= SERIAL_XMIT_SIZE) - dport->xmit_tail -= SERIAL_XMIT_SIZE; - } - atomic_sub(number_written, &dashtty_xmit_cnt); - } - mutex_unlock(&dport->xmit_lock); - - /* if we've made more data available, wake up tty */ - if (count && number_written) { - tty = tty_port_tty_get(&dport->port); - if (tty) { - tty_wakeup(tty); - tty_kref_put(tty); - } - } - - /* did the write fail? */ - return count && !number_written; -} - -/** - * put_data() - Kernel thread to write out blocks of channel data to DA. - * @arg: Unused. - * - * This kernel thread runs while @dashtty_xmit_cnt != 0, and loops over the - * channels to write out any buffered data. If any of the channels stall due to - * the remote buffer being full, a hold off happens to allow the debugger to - * drain the buffer. - */ -static int put_data(void *arg) -{ - unsigned int chan, stall; - - __set_current_state(TASK_RUNNING); - while (!kthread_should_stop()) { - /* - * For each channel see if there's anything to transmit in the - * port's xmit_buf. - */ - stall = 0; - for (chan = 0; chan < NUM_TTY_CHANNELS; ++chan) - stall += put_channel_data(chan); - - /* - * If some of the buffers are full, hold off for a short while - * to allow them to empty. - */ - if (stall) - msleep(25); - - wait_event_interruptible(dashtty_waitqueue, - atomic_read(&dashtty_xmit_cnt)); - } - - return 0; -} - -/* - * This gets called every DA_TTY_POLL and polls the channels for data - */ -static void dashtty_timer(struct timer_list *poll_timer) -{ - int channel; - - /* If there are no ports open do nothing and don't poll again. */ - if (!atomic_read(&num_channels_need_poll)) - return; - - channel = find_channel_to_poll(); - - /* Did we find a channel to poll? */ - if (channel >= 0) - fetch_data(channel); - - mod_timer(poll_timer, jiffies + DA_TTY_POLL); -} - -static void add_poll_timer(struct timer_list *poll_timer) -{ - timer_setup(poll_timer, dashtty_timer, TIMER_PINNED); - poll_timer->expires = jiffies + DA_TTY_POLL; - - /* - * Always attach the timer to the boot CPU. The DA channels are per-CPU - * so all polling should be from a single CPU. - */ - add_timer_on(poll_timer, 0); -} - -static int dashtty_port_activate(struct tty_port *port, struct tty_struct *tty) -{ - struct dashtty_port *dport = container_of(port, struct dashtty_port, - port); - void *rx_buf; - - /* Allocate the buffer we use for writing data */ - if (tty_port_alloc_xmit_buf(port) < 0) - goto err; - - /* Allocate the buffer we use for reading data */ - rx_buf = kzalloc(RX_BUF_SIZE, GFP_KERNEL); - if (!rx_buf) - goto err_free_xmit; - - spin_lock_bh(&dport->rx_lock); - dport->rx_buf = rx_buf; - spin_unlock_bh(&dport->rx_lock); - - /* - * Don't add the poll timer if we're opening a console. This - * avoids the overhead of polling the Dash but means it is not - * possible to have a login on /dev/console. - * - */ - if (console_poll || dport != &dashtty_ports[CONSOLE_CHANNEL]) - if (atomic_inc_return(&num_channels_need_poll) == 1) - add_poll_timer(&poll_timer); - - return 0; -err_free_xmit: - tty_port_free_xmit_buf(port); -err: - return -ENOMEM; -} - -static void dashtty_port_shutdown(struct tty_port *port) -{ - struct dashtty_port *dport = container_of(port, struct dashtty_port, - port); - void *rx_buf; - unsigned int count; - - /* stop reading */ - if (console_poll || dport != &dashtty_ports[CONSOLE_CHANNEL]) - if (atomic_dec_and_test(&num_channels_need_poll)) - del_timer_sync(&poll_timer); - - mutex_lock(&dport->xmit_lock); - count = dport->xmit_cnt; - mutex_unlock(&dport->xmit_lock); - if (count) { - /* - * There's still data to write out, so wake and wait for the - * writer thread to drain the buffer. - */ - del_timer(&put_timer); - wake_up_interruptible(&dashtty_waitqueue); - wait_for_completion(&dport->xmit_empty); - } - - /* Null the read buffer (timer could still be running!) */ - spin_lock_bh(&dport->rx_lock); - rx_buf = dport->rx_buf; - dport->rx_buf = NULL; - spin_unlock_bh(&dport->rx_lock); - /* Free the read buffer */ - kfree(rx_buf); - - /* Free the write buffer */ - tty_port_free_xmit_buf(port); -} - -static const struct tty_port_operations dashtty_port_ops = { - .activate = dashtty_port_activate, - .shutdown = dashtty_port_shutdown, -}; - -static int dashtty_install(struct tty_driver *driver, struct tty_struct *tty) -{ - return tty_port_install(&dashtty_ports[tty->index].port, driver, tty); -} - -static int dashtty_open(struct tty_struct *tty, struct file *filp) -{ - return tty_port_open(tty->port, tty, filp); -} - -static void dashtty_close(struct tty_struct *tty, struct file *filp) -{ - return tty_port_close(tty->port, tty, filp); -} - -static void dashtty_hangup(struct tty_struct *tty) -{ - int channel; - struct dashtty_port *dport; - - channel = tty->index; - dport = &dashtty_ports[channel]; - - /* drop any data in the xmit buffer */ - mutex_lock(&dport->xmit_lock); - if (dport->xmit_cnt) { - atomic_sub(dport->xmit_cnt, &dashtty_xmit_cnt); - dport->xmit_cnt = 0; - dport->xmit_head = 0; - dport->xmit_tail = 0; - complete(&dport->xmit_empty); - } - mutex_unlock(&dport->xmit_lock); - - tty_port_hangup(tty->port); -} - -/** - * dashtty_put_timer() - Delayed wake up of kernel thread. - * @ignored: unused - * - * This timer function wakes up the kernel thread if any data exists in the - * buffers. It is used to delay the expensive writeout until the writer has - * stopped writing. - */ -static void dashtty_put_timer(struct timer_list *unused) -{ - if (atomic_read(&dashtty_xmit_cnt)) - wake_up_interruptible(&dashtty_waitqueue); -} - -static int dashtty_write(struct tty_struct *tty, const unsigned char *buf, - int total) -{ - int channel, count, block; - struct dashtty_port *dport; - - /* Determine the channel */ - channel = tty->index; - dport = &dashtty_ports[channel]; - - /* - * Write to output buffer. - * - * The reason that we asynchronously write the buffer is because if we - * were to write the buffer synchronously then because DA channels are - * per-CPU the buffer would be written to the channel of whatever CPU - * we're running on. - * - * What we actually want to happen is have all input and output done on - * one CPU. - */ - mutex_lock(&dport->xmit_lock); - /* work out how many bytes we can write to the xmit buffer */ - total = min(total, (int)(SERIAL_XMIT_SIZE - dport->xmit_cnt)); - atomic_add(total, &dashtty_xmit_cnt); - dport->xmit_cnt += total; - /* write the actual bytes (may need splitting if it wraps) */ - for (count = total; count; count -= block) { - block = min(count, (int)(SERIAL_XMIT_SIZE - dport->xmit_head)); - memcpy(dport->port.xmit_buf + dport->xmit_head, buf, block); - dport->xmit_head += block; - if (dport->xmit_head >= SERIAL_XMIT_SIZE) - dport->xmit_head -= SERIAL_XMIT_SIZE; - buf += block; - } - count = dport->xmit_cnt; - /* xmit buffer no longer empty? */ - if (count) - reinit_completion(&dport->xmit_empty); - mutex_unlock(&dport->xmit_lock); - - if (total) { - /* - * If the buffer is full, wake up the kthread, otherwise allow - * some more time for the buffer to fill up a bit before waking - * it. - */ - if (count == SERIAL_XMIT_SIZE) { - del_timer(&put_timer); - wake_up_interruptible(&dashtty_waitqueue); - } else { - mod_timer(&put_timer, jiffies + DA_TTY_PUT_DELAY); - } - } - return total; -} - -static int dashtty_write_room(struct tty_struct *tty) -{ - struct dashtty_port *dport; - int channel; - int room; - - channel = tty->index; - dport = &dashtty_ports[channel]; - - /* report the space in the xmit buffer */ - mutex_lock(&dport->xmit_lock); - room = SERIAL_XMIT_SIZE - dport->xmit_cnt; - mutex_unlock(&dport->xmit_lock); - - return room; -} - -static int dashtty_chars_in_buffer(struct tty_struct *tty) -{ - struct dashtty_port *dport; - int channel; - int chars; - - channel = tty->index; - dport = &dashtty_ports[channel]; - - /* report the number of bytes in the xmit buffer */ - mutex_lock(&dport->xmit_lock); - chars = dport->xmit_cnt; - mutex_unlock(&dport->xmit_lock); - - return chars; -} - -static const struct tty_operations dashtty_ops = { - .install = dashtty_install, - .open = dashtty_open, - .close = dashtty_close, - .hangup = dashtty_hangup, - .write = dashtty_write, - .write_room = dashtty_write_room, - .chars_in_buffer = dashtty_chars_in_buffer, -}; - -static int __init dashtty_init(void) -{ - int ret; - int nport; - struct dashtty_port *dport; - - if (!metag_da_enabled()) - return -ENODEV; - - channel_driver = tty_alloc_driver(NUM_TTY_CHANNELS, - TTY_DRIVER_REAL_RAW); - if (IS_ERR(channel_driver)) - return PTR_ERR(channel_driver); - - channel_driver->driver_name = "metag_da"; - channel_driver->name = "ttyDA"; - channel_driver->major = DA_TTY_MAJOR; - channel_driver->minor_start = 0; - channel_driver->type = TTY_DRIVER_TYPE_SERIAL; - channel_driver->subtype = SERIAL_TYPE_NORMAL; - channel_driver->init_termios = tty_std_termios; - channel_driver->init_termios.c_cflag |= CLOCAL; - - tty_set_operations(channel_driver, &dashtty_ops); - for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { - dport = &dashtty_ports[nport]; - tty_port_init(&dport->port); - dport->port.ops = &dashtty_port_ops; - spin_lock_init(&dport->rx_lock); - mutex_init(&dport->xmit_lock); - /* the xmit buffer starts empty, i.e. completely written */ - init_completion(&dport->xmit_empty); - complete(&dport->xmit_empty); - } - - timer_setup(&put_timer, dashtty_put_timer, 0); - - init_waitqueue_head(&dashtty_waitqueue); - dashtty_thread = kthread_create(put_data, NULL, "ttyDA"); - if (IS_ERR(dashtty_thread)) { - pr_err("Couldn't create dashtty thread\n"); - ret = PTR_ERR(dashtty_thread); - goto err_destroy_ports; - } - /* - * Bind the writer thread to the boot CPU so it can't migrate. - * DA channels are per-CPU and we want all channel I/O to be on a single - * predictable CPU. - */ - kthread_bind(dashtty_thread, 0); - wake_up_process(dashtty_thread); - - ret = tty_register_driver(channel_driver); - - if (ret < 0) { - pr_err("Couldn't install dashtty driver: err %d\n", - ret); - goto err_stop_kthread; - } - - return 0; - -err_stop_kthread: - kthread_stop(dashtty_thread); -err_destroy_ports: - for (nport = 0; nport < NUM_TTY_CHANNELS; nport++) { - dport = &dashtty_ports[nport]; - tty_port_destroy(&dport->port); - } - put_tty_driver(channel_driver); - return ret; -} -device_initcall(dashtty_init); - -#ifdef CONFIG_DA_CONSOLE - -static void dash_console_write(struct console *co, const char *s, - unsigned int count) -{ - int actually_written; - - chancall(WRBUF, CONSOLE_CHANNEL, count, (void *)s, &actually_written); -} - -static struct tty_driver *dash_console_device(struct console *c, int *index) -{ - *index = c->index; - return channel_driver; -} - -struct console dash_console = { - .name = "ttyDA", - .write = dash_console_write, - .device = dash_console_device, - .flags = CON_PRINTBUFFER, - .index = 1, -}; - -#endif -- cgit v1.2.3-59-g8ed1b From b9b2909093ede6f0cea2beff201264f431504de3 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 21 Feb 2018 16:38:06 +0000 Subject: watchdog: imgpdc: Drop METAG dependency Now that arch/metag/ has been removed, remove the METAG dependency from the IMG IR device driver. The hardware is also present on MIPS SoCs so the driver still has value. Signed-off-by: James Hogan Acked-by: Guenter Roeck Cc: Wim Van Sebroeck Cc: linux-watchdog@vger.kernel.org Cc: linux-metag@vger.kernel.org --- drivers/watchdog/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index aff773bcebdb..152268010c45 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -1602,7 +1602,7 @@ config BCM7038_WDT config IMGPDC_WDT tristate "Imagination Technologies PDC Watchdog Timer" depends on HAS_IOMEM - depends on METAG || MIPS || COMPILE_TEST + depends on MIPS || COMPILE_TEST select WATCHDOG_CORE help Driver for Imagination Technologies PowerDown Controller -- cgit v1.2.3-59-g8ed1b From 43e951e744462bf10c2dc8548263095ed4aa9e7d Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 21 Feb 2018 16:02:10 +0000 Subject: media: img-ir: Drop METAG dependency Now that arch/metag/ has been removed, remove the METAG dependency from the IMG IR device driver. The hardware is also present on MIPS SoCs so the driver still has value. Signed-off-by: James Hogan Acked-by: Sean Young Cc: Mauro Carvalho Chehab Cc: Mauro Carvalho Chehab Cc: linux-media@vger.kernel.org Cc: linux-metag@vger.kernel.org --- drivers/media/rc/img-ir/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/media/rc/img-ir/Kconfig b/drivers/media/rc/img-ir/Kconfig index a896d3c83a1c..d2c6617d468e 100644 --- a/drivers/media/rc/img-ir/Kconfig +++ b/drivers/media/rc/img-ir/Kconfig @@ -1,7 +1,7 @@ config IR_IMG tristate "ImgTec IR Decoder" depends on RC_CORE - depends on METAG || MIPS || COMPILE_TEST + depends on MIPS || COMPILE_TEST select IR_IMG_HW if !IR_IMG_RAW help Say Y or M here if you want to use the ImgTec infrared decoder -- cgit v1.2.3-59-g8ed1b From 8d06c3302635f0ab426937f2bb10e9b9c34087e4 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Wed, 21 Feb 2018 15:54:54 +0000 Subject: i2c: img-scb: Drop METAG dependency Now that arch/metag/ has been removed, remove the METAG dependency from the IMG SCB I2C device driver. The hardware is also present on MIPS SoCs so the driver still has value. Signed-off-by: James Hogan Acked-by: Wolfram Sang Cc: linux-i2c@vger.kernel.org Cc: linux-metag@vger.kernel.org --- drivers/i2c/busses/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index a9805c7cb305..94f419489a0b 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -635,7 +635,7 @@ config I2C_IBM_IIC config I2C_IMG tristate "Imagination Technologies I2C SCB Controller" - depends on MIPS || METAG || COMPILE_TEST + depends on MIPS || COMPILE_TEST help Say Y here if you want to use the IMG I2C SCB controller, available on the TZ1090 and other IMG SoCs. -- cgit v1.2.3-59-g8ed1b