From patchwork Fri Jan 13 06:23:19 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642276 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 67458C678D9 for ; Fri, 13 Jan 2023 06:25:02 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S239524AbjAMGY7 (ORCPT ); Fri, 13 Jan 2023 01:24:59 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236259AbjAMGYQ (ORCPT ); Fri, 13 Jan 2023 01:24:16 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 469BF5BA26; Thu, 12 Jan 2023 22:23:57 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=pE5vHsweVi9sw+XFtbQOjd8ZmlFDvTP0hqXRxtOPgdI=; b=UPm4fiFNqG828TmS+12Rola8gO eqHlHcKs17NiINhJVso8pQaJLXAawxXFCKuLlP7HRjKIjJN2ZXqL/cl3jIEux4plqaePmjKWoVYai QlJizCpTb7yVhQxL/QJWjJ37KmX8qVxA7Rot4hYXsbm50Ukgoehbb75E6d7ZbOqa0NS55yCF1vD12 hTv+9XqO7HKABDyO220qXwurWxcmgcwBxl9/GRlKpDUCPyGWGMAz1KKVnajqZK+KC0juYlZ2W8UlT 3xv/hB5gSMNo2fI0kJb/GNm6IFqQb0S3ZTYgJMi4xbRkGq5u2ysaI8Zc1eFL7BGimSK1gVFq75foe LEx3cuRw==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDTf-000lNa-NO; Fri, 13 Jan 2023 06:23:48 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 02/22] usb: remove the dead USB_OHCI_SH option Date: Fri, 13 Jan 2023 07:23:19 +0100 Message-Id: <20230113062339.1909087-3-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org USB_OHCI_SH is a dummy option that never builds any code, remove it. Signed-off-by: Christoph Hellwig --- drivers/usb/host/Kconfig | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 8d799d23c476e1..ca5f657c092cf4 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -548,17 +548,6 @@ config USB_OHCI_HCD_SSB If unsure, say N. -config USB_OHCI_SH - bool "OHCI support for SuperH USB controller (DEPRECATED)" - depends on SUPERH || COMPILE_TEST - select USB_OHCI_HCD_PLATFORM - help - This option is deprecated now and the driver was removed, use - USB_OHCI_HCD_PLATFORM instead. - - Enables support for the on-chip OHCI controller on the SuperH. - If you use the PCI OHCI controller, this option is not necessary. - config USB_OHCI_EXYNOS tristate "OHCI support for Samsung S5P/Exynos SoC Series" depends on ARCH_S5PV210 || ARCH_EXYNOS || COMPILE_TEST From patchwork Fri Jan 13 06:23:21 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642275 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E3A8AC7112F for ; Fri, 13 Jan 2023 06:25:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234092AbjAMGZX (ORCPT ); Fri, 13 Jan 2023 01:25:23 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239005AbjAMGYb (ORCPT ); Fri, 13 Jan 2023 01:24:31 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F1E0669B33; Thu, 12 Jan 2023 22:24:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=YWdaNZZD6eiGGHiQwqB4d/n7vbdllZAZ4PVlQ9KrUog=; b=XtPGvVCciAHH/ZLi442ryHF6rq FvgKnRpeqvwCx9UPgqvxyoSez2P7/TsQH4CCdKmAVKMjtEs7KN5fhRpLHTjMdmTb4fMzzf6CmNKlf rXdbPlEScIlBvjJrEpLQ9Qz+cT5QX9vrjKWKFTMLmEzur4VlSN6Xl4jhStM3ZSCwOvwfNkCRTuNnR wJyIbeNnp1Bzl3/RFdCiY+e0gUrTlrvJFtmxx0gpbmv+sIP/JUZGEtJIDk593yDFSk9RClQJfmg7Y 4kjnLNtrXGl9NJsEFRSHVUmWUakVHMHmyXzQxjKYElq0QLSA3Qcs/NoVXvf4FXw2zlWkEQ7IFJk43 R2e+Go7Q==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDTr-000lRy-FI; Fri, 13 Jan 2023 06:24:00 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 04/22] sound: remove sound/sh Date: Fri, 13 Jan 2023 07:23:21 +0100 Message-Id: <20230113062339.1909087-5-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that arch/sh is removed these drivers are dead code. Signed-off-by: Christoph Hellwig --- sound/Kconfig | 2 - sound/Makefile | 2 +- sound/sh/Kconfig | 32 -- sound/sh/Makefile | 11 - sound/sh/aica.c | 628 ---------------------------------------- sound/sh/aica.h | 68 ----- sound/sh/sh_dac_audio.c | 412 -------------------------- 7 files changed, 1 insertion(+), 1154 deletions(-) delete mode 100644 sound/sh/Kconfig delete mode 100644 sound/sh/Makefile delete mode 100644 sound/sh/aica.c delete mode 100644 sound/sh/aica.h delete mode 100644 sound/sh/sh_dac_audio.c diff --git a/sound/Kconfig b/sound/Kconfig index e56d96d2b11cae..14361bb428baa1 100644 --- a/sound/Kconfig +++ b/sound/Kconfig @@ -75,8 +75,6 @@ source "sound/spi/Kconfig" source "sound/mips/Kconfig" -source "sound/sh/Kconfig" - # the following will depend on the order of config. # here assuming USB is defined before ALSA source "sound/usb/Kconfig" diff --git a/sound/Makefile b/sound/Makefile index 04ef04b1168f39..bb4b8806321c67 100644 --- a/sound/Makefile +++ b/sound/Makefile @@ -4,7 +4,7 @@ obj-$(CONFIG_SOUND) += soundcore.o obj-$(CONFIG_DMASOUND) += oss/dmasound/ -obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \ +obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ synth/ usb/ \ firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ hda/ x86/ xen/ \ virtio/ obj-$(CONFIG_SND_AOA) += aoa/ diff --git a/sound/sh/Kconfig b/sound/sh/Kconfig deleted file mode 100644 index b75fbb3236a7b9..00000000000000 --- a/sound/sh/Kconfig +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# ALSA SH drivers - -menuconfig SND_SUPERH - bool "SUPERH sound devices" - depends on SUPERH - default y - help - Support for sound devices specific to SUPERH architectures. - Drivers that are implemented on ASoC can be found in - "ALSA for SoC audio support" section. - -if SND_SUPERH - -config SND_AICA - tristate "Dreamcast Yamaha AICA sound" - depends on SH_DREAMCAST - select SND_PCM - select G2_DMA - help - ALSA Sound driver for the SEGA Dreamcast console. - -config SND_SH_DAC_AUDIO - tristate "SuperH DAC audio support" - depends on SND - depends on CPU_SH3 && HIGH_RES_TIMERS - select SND_PCM - help - Say Y here to include support for the on-chip DAC. - -endif # SND_SUPERH - diff --git a/sound/sh/Makefile b/sound/sh/Makefile deleted file mode 100644 index c0bbc500c17c73..00000000000000 --- a/sound/sh/Makefile +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for ALSA -# - -snd-aica-objs := aica.o -snd-sh_dac_audio-objs := sh_dac_audio.o - -# Toplevel Module Dependency -obj-$(CONFIG_SND_AICA) += snd-aica.o -obj-$(CONFIG_SND_SH_DAC_AUDIO) += snd-sh_dac_audio.o diff --git a/sound/sh/aica.c b/sound/sh/aica.c deleted file mode 100644 index 6e9d6bd67369af..00000000000000 --- a/sound/sh/aica.c +++ /dev/null @@ -1,628 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* -* -* Copyright Adrian McMenamin 2005, 2006, 2007 -* -* Requires firmware (BSD licenced) available from: -* http://linuxdc.cvs.sourceforge.net/linuxdc/linux-sh-dc/sound/oss/aica/firmware/ -* or the maintainer -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "aica.h" - -MODULE_AUTHOR("Adrian McMenamin "); -MODULE_DESCRIPTION("Dreamcast AICA sound (pcm) driver"); -MODULE_LICENSE("GPL"); -MODULE_FIRMWARE("aica_firmware.bin"); - -/* module parameters */ -#define CARD_NAME "AICA" -static int index = -1; -static char *id; -static bool enable = 1; -module_param(index, int, 0444); -MODULE_PARM_DESC(index, "Index value for " CARD_NAME " soundcard."); -module_param(id, charp, 0444); -MODULE_PARM_DESC(id, "ID string for " CARD_NAME " soundcard."); -module_param(enable, bool, 0644); -MODULE_PARM_DESC(enable, "Enable " CARD_NAME " soundcard."); - -/* Simple platform device */ -static struct platform_device *pd; -static struct resource aica_memory_space[2] = { - { - .name = "AICA ARM CONTROL", - .start = ARM_RESET_REGISTER, - .flags = IORESOURCE_MEM, - .end = ARM_RESET_REGISTER + 3, - }, - { - .name = "AICA Sound RAM", - .start = SPU_MEMORY_BASE, - .flags = IORESOURCE_MEM, - .end = SPU_MEMORY_BASE + 0x200000 - 1, - }, -}; - -/* SPU specific functions */ -/* spu_write_wait - wait for G2-SH FIFO to clear */ -static void spu_write_wait(void) -{ - int time_count; - time_count = 0; - while (1) { - if (!(readl(G2_FIFO) & 0x11)) - break; - /* To ensure hardware failure doesn't wedge kernel */ - time_count++; - if (time_count > 0x10000) { - snd_printk - ("WARNING: G2 FIFO appears to be blocked.\n"); - break; - } - } -} - -/* spu_memset - write to memory in SPU address space */ -static void spu_memset(u32 toi, u32 what, int length) -{ - int i; - unsigned long flags; - if (snd_BUG_ON(length % 4)) - return; - for (i = 0; i < length; i++) { - if (!(i % 8)) - spu_write_wait(); - local_irq_save(flags); - writel(what, toi + SPU_MEMORY_BASE); - local_irq_restore(flags); - toi++; - } -} - -/* spu_memload - write to SPU address space */ -static void spu_memload(u32 toi, const void *from, int length) -{ - unsigned long flags; - const u32 *froml = from; - u32 __iomem *to = (u32 __iomem *) (SPU_MEMORY_BASE + toi); - int i; - u32 val; - length = DIV_ROUND_UP(length, 4); - spu_write_wait(); - for (i = 0; i < length; i++) { - if (!(i % 8)) - spu_write_wait(); - val = *froml; - local_irq_save(flags); - writel(val, to); - local_irq_restore(flags); - froml++; - to++; - } -} - -/* spu_disable - set spu registers to stop sound output */ -static void spu_disable(void) -{ - int i; - unsigned long flags; - u32 regval; - spu_write_wait(); - regval = readl(ARM_RESET_REGISTER); - regval |= 1; - spu_write_wait(); - local_irq_save(flags); - writel(regval, ARM_RESET_REGISTER); - local_irq_restore(flags); - for (i = 0; i < 64; i++) { - spu_write_wait(); - regval = readl(SPU_REGISTER_BASE + (i * 0x80)); - regval = (regval & ~0x4000) | 0x8000; - spu_write_wait(); - local_irq_save(flags); - writel(regval, SPU_REGISTER_BASE + (i * 0x80)); - local_irq_restore(flags); - } -} - -/* spu_enable - set spu registers to enable sound output */ -static void spu_enable(void) -{ - unsigned long flags; - u32 regval = readl(ARM_RESET_REGISTER); - regval &= ~1; - spu_write_wait(); - local_irq_save(flags); - writel(regval, ARM_RESET_REGISTER); - local_irq_restore(flags); -} - -/* - * Halt the sound processor, clear the memory, - * load some default ARM7 code, and then restart ARM7 -*/ -static void spu_reset(void) -{ - unsigned long flags; - spu_disable(); - spu_memset(0, 0, 0x200000 / 4); - /* Put ARM7 in endless loop */ - local_irq_save(flags); - __raw_writel(0xea000002, SPU_MEMORY_BASE); - local_irq_restore(flags); - spu_enable(); -} - -/* aica_chn_start - write to spu to start playback */ -static void aica_chn_start(void) -{ - unsigned long flags; - spu_write_wait(); - local_irq_save(flags); - writel(AICA_CMD_KICK | AICA_CMD_START, (u32 *) AICA_CONTROL_POINT); - local_irq_restore(flags); -} - -/* aica_chn_halt - write to spu to halt playback */ -static void aica_chn_halt(void) -{ - unsigned long flags; - spu_write_wait(); - local_irq_save(flags); - writel(AICA_CMD_KICK | AICA_CMD_STOP, (u32 *) AICA_CONTROL_POINT); - local_irq_restore(flags); -} - -/* ALSA code below */ -static const struct snd_pcm_hardware snd_pcm_aica_playback_hw = { - .info = (SNDRV_PCM_INFO_NONINTERLEAVED), - .formats = - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_IMA_ADPCM), - .rates = SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 1, - .channels_max = 2, - .buffer_bytes_max = AICA_BUFFER_SIZE, - .period_bytes_min = AICA_PERIOD_SIZE, - .period_bytes_max = AICA_PERIOD_SIZE, - .periods_min = AICA_PERIOD_NUMBER, - .periods_max = AICA_PERIOD_NUMBER, -}; - -static int aica_dma_transfer(int channels, int buffer_size, - struct snd_pcm_substream *substream) -{ - int q, err, period_offset; - struct snd_card_aica *dreamcastcard; - struct snd_pcm_runtime *runtime; - unsigned long flags; - err = 0; - dreamcastcard = substream->pcm->private_data; - period_offset = dreamcastcard->clicks; - period_offset %= (AICA_PERIOD_NUMBER / channels); - runtime = substream->runtime; - for (q = 0; q < channels; q++) { - local_irq_save(flags); - err = dma_xfer(AICA_DMA_CHANNEL, - (unsigned long) (runtime->dma_area + - (AICA_BUFFER_SIZE * q) / - channels + - AICA_PERIOD_SIZE * - period_offset), - AICA_CHANNEL0_OFFSET + q * CHANNEL_OFFSET + - AICA_PERIOD_SIZE * period_offset, - buffer_size / channels, AICA_DMA_MODE); - if (unlikely(err < 0)) { - local_irq_restore(flags); - break; - } - dma_wait_for_completion(AICA_DMA_CHANNEL); - local_irq_restore(flags); - } - return err; -} - -static void startup_aica(struct snd_card_aica *dreamcastcard) -{ - spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, - dreamcastcard->channel, sizeof(struct aica_channel)); - aica_chn_start(); -} - -static void run_spu_dma(struct work_struct *work) -{ - int buffer_size; - struct snd_pcm_runtime *runtime; - struct snd_card_aica *dreamcastcard; - dreamcastcard = - container_of(work, struct snd_card_aica, spu_dma_work); - runtime = dreamcastcard->substream->runtime; - if (unlikely(dreamcastcard->dma_check == 0)) { - buffer_size = - frames_to_bytes(runtime, runtime->buffer_size); - if (runtime->channels > 1) - dreamcastcard->channel->flags |= 0x01; - aica_dma_transfer(runtime->channels, buffer_size, - dreamcastcard->substream); - startup_aica(dreamcastcard); - dreamcastcard->clicks = - buffer_size / (AICA_PERIOD_SIZE * runtime->channels); - return; - } else { - aica_dma_transfer(runtime->channels, - AICA_PERIOD_SIZE * runtime->channels, - dreamcastcard->substream); - snd_pcm_period_elapsed(dreamcastcard->substream); - dreamcastcard->clicks++; - if (unlikely(dreamcastcard->clicks >= AICA_PERIOD_NUMBER)) - dreamcastcard->clicks %= AICA_PERIOD_NUMBER; - mod_timer(&dreamcastcard->timer, jiffies + 1); - } -} - -static void aica_period_elapsed(struct timer_list *t) -{ - struct snd_card_aica *dreamcastcard = from_timer(dreamcastcard, - t, timer); - struct snd_pcm_substream *substream = dreamcastcard->substream; - /*timer function - so cannot sleep */ - int play_period; - struct snd_pcm_runtime *runtime; - runtime = substream->runtime; - dreamcastcard = substream->pcm->private_data; - /* Have we played out an additional period? */ - play_period = - frames_to_bytes(runtime, - readl - (AICA_CONTROL_CHANNEL_SAMPLE_NUMBER)) / - AICA_PERIOD_SIZE; - if (play_period == dreamcastcard->current_period) { - /* reschedule the timer */ - mod_timer(&(dreamcastcard->timer), jiffies + 1); - return; - } - if (runtime->channels > 1) - dreamcastcard->current_period = play_period; - if (unlikely(dreamcastcard->dma_check == 0)) - dreamcastcard->dma_check = 1; - schedule_work(&(dreamcastcard->spu_dma_work)); -} - -static void spu_begin_dma(struct snd_pcm_substream *substream) -{ - struct snd_card_aica *dreamcastcard; - struct snd_pcm_runtime *runtime; - runtime = substream->runtime; - dreamcastcard = substream->pcm->private_data; - /*get the queue to do the work */ - schedule_work(&(dreamcastcard->spu_dma_work)); - mod_timer(&dreamcastcard->timer, jiffies + 4); -} - -static int snd_aicapcm_pcm_open(struct snd_pcm_substream - *substream) -{ - struct snd_pcm_runtime *runtime; - struct aica_channel *channel; - struct snd_card_aica *dreamcastcard; - if (!enable) - return -ENOENT; - dreamcastcard = substream->pcm->private_data; - channel = kmalloc(sizeof(struct aica_channel), GFP_KERNEL); - if (!channel) - return -ENOMEM; - /* set defaults for channel */ - channel->sfmt = SM_8BIT; - channel->cmd = AICA_CMD_START; - channel->vol = dreamcastcard->master_volume; - channel->pan = 0x80; - channel->pos = 0; - channel->flags = 0; /* default to mono */ - dreamcastcard->channel = channel; - runtime = substream->runtime; - runtime->hw = snd_pcm_aica_playback_hw; - spu_enable(); - dreamcastcard->clicks = 0; - dreamcastcard->current_period = 0; - dreamcastcard->dma_check = 0; - return 0; -} - -static int snd_aicapcm_pcm_close(struct snd_pcm_substream - *substream) -{ - struct snd_card_aica *dreamcastcard = substream->pcm->private_data; - flush_work(&(dreamcastcard->spu_dma_work)); - del_timer(&dreamcastcard->timer); - dreamcastcard->substream = NULL; - kfree(dreamcastcard->channel); - spu_disable(); - return 0; -} - -static int snd_aicapcm_pcm_prepare(struct snd_pcm_substream - *substream) -{ - struct snd_card_aica *dreamcastcard = substream->pcm->private_data; - if ((substream->runtime)->format == SNDRV_PCM_FORMAT_S16_LE) - dreamcastcard->channel->sfmt = SM_16BIT; - dreamcastcard->channel->freq = substream->runtime->rate; - dreamcastcard->substream = substream; - return 0; -} - -static int snd_aicapcm_pcm_trigger(struct snd_pcm_substream - *substream, int cmd) -{ - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - spu_begin_dma(substream); - break; - case SNDRV_PCM_TRIGGER_STOP: - aica_chn_halt(); - break; - default: - return -EINVAL; - } - return 0; -} - -static unsigned long snd_aicapcm_pcm_pointer(struct snd_pcm_substream - *substream) -{ - return readl(AICA_CONTROL_CHANNEL_SAMPLE_NUMBER); -} - -static const struct snd_pcm_ops snd_aicapcm_playback_ops = { - .open = snd_aicapcm_pcm_open, - .close = snd_aicapcm_pcm_close, - .prepare = snd_aicapcm_pcm_prepare, - .trigger = snd_aicapcm_pcm_trigger, - .pointer = snd_aicapcm_pcm_pointer, -}; - -/* TO DO: set up to handle more than one pcm instance */ -static int __init snd_aicapcmchip(struct snd_card_aica - *dreamcastcard, int pcm_index) -{ - struct snd_pcm *pcm; - int err; - /* AICA has no capture ability */ - err = - snd_pcm_new(dreamcastcard->card, "AICA PCM", pcm_index, 1, 0, - &pcm); - if (unlikely(err < 0)) - return err; - pcm->private_data = dreamcastcard; - strcpy(pcm->name, "AICA PCM"); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, - &snd_aicapcm_playback_ops); - /* Allocate the DMA buffers */ - snd_pcm_set_managed_buffer_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - NULL, - AICA_BUFFER_SIZE, - AICA_BUFFER_SIZE); - return 0; -} - -/* Mixer controls */ -#define aica_pcmswitch_info snd_ctl_boolean_mono_info - -static int aica_pcmswitch_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.integer.value[0] = 1; /* TO DO: Fix me */ - return 0; -} - -static int aica_pcmswitch_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - if (ucontrol->value.integer.value[0] == 1) - return 0; /* TO DO: Fix me */ - else - aica_chn_halt(); - return 0; -} - -static int aica_pcmvolume_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 1; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = 0xFF; - return 0; -} - -static int aica_pcmvolume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_card_aica *dreamcastcard; - dreamcastcard = kcontrol->private_data; - if (unlikely(!dreamcastcard->channel)) - return -ETXTBSY; /* we've not yet been set up */ - ucontrol->value.integer.value[0] = dreamcastcard->channel->vol; - return 0; -} - -static int aica_pcmvolume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_card_aica *dreamcastcard; - unsigned int vol; - dreamcastcard = kcontrol->private_data; - if (unlikely(!dreamcastcard->channel)) - return -ETXTBSY; - vol = ucontrol->value.integer.value[0]; - if (vol > 0xff) - return -EINVAL; - if (unlikely(dreamcastcard->channel->vol == vol)) - return 0; - dreamcastcard->channel->vol = ucontrol->value.integer.value[0]; - dreamcastcard->master_volume = ucontrol->value.integer.value[0]; - spu_memload(AICA_CHANNEL0_CONTROL_OFFSET, - dreamcastcard->channel, sizeof(struct aica_channel)); - return 1; -} - -static const struct snd_kcontrol_new snd_aica_pcmswitch_control = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Switch", - .index = 0, - .info = aica_pcmswitch_info, - .get = aica_pcmswitch_get, - .put = aica_pcmswitch_put -}; - -static const struct snd_kcontrol_new snd_aica_pcmvolume_control = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", - .index = 0, - .info = aica_pcmvolume_info, - .get = aica_pcmvolume_get, - .put = aica_pcmvolume_put -}; - -static int load_aica_firmware(void) -{ - int err; - const struct firmware *fw_entry; - spu_reset(); - err = request_firmware(&fw_entry, "aica_firmware.bin", &pd->dev); - if (unlikely(err)) - return err; - /* write firmware into memory */ - spu_disable(); - spu_memload(0, fw_entry->data, fw_entry->size); - spu_enable(); - release_firmware(fw_entry); - return err; -} - -static int add_aicamixer_controls(struct snd_card_aica *dreamcastcard) -{ - int err; - err = snd_ctl_add - (dreamcastcard->card, - snd_ctl_new1(&snd_aica_pcmvolume_control, dreamcastcard)); - if (unlikely(err < 0)) - return err; - err = snd_ctl_add - (dreamcastcard->card, - snd_ctl_new1(&snd_aica_pcmswitch_control, dreamcastcard)); - if (unlikely(err < 0)) - return err; - return 0; -} - -static int snd_aica_remove(struct platform_device *devptr) -{ - struct snd_card_aica *dreamcastcard; - dreamcastcard = platform_get_drvdata(devptr); - if (unlikely(!dreamcastcard)) - return -ENODEV; - snd_card_free(dreamcastcard->card); - kfree(dreamcastcard); - return 0; -} - -static int snd_aica_probe(struct platform_device *devptr) -{ - int err; - struct snd_card_aica *dreamcastcard; - dreamcastcard = kzalloc(sizeof(struct snd_card_aica), GFP_KERNEL); - if (unlikely(!dreamcastcard)) - return -ENOMEM; - err = snd_card_new(&devptr->dev, index, SND_AICA_DRIVER, - THIS_MODULE, 0, &dreamcastcard->card); - if (unlikely(err < 0)) { - kfree(dreamcastcard); - return err; - } - strcpy(dreamcastcard->card->driver, "snd_aica"); - strcpy(dreamcastcard->card->shortname, SND_AICA_DRIVER); - strcpy(dreamcastcard->card->longname, - "Yamaha AICA Super Intelligent Sound Processor for SEGA Dreamcast"); - /* Prepare to use the queue */ - INIT_WORK(&(dreamcastcard->spu_dma_work), run_spu_dma); - timer_setup(&dreamcastcard->timer, aica_period_elapsed, 0); - /* Load the PCM 'chip' */ - err = snd_aicapcmchip(dreamcastcard, 0); - if (unlikely(err < 0)) - goto freedreamcast; - /* Add basic controls */ - err = add_aicamixer_controls(dreamcastcard); - if (unlikely(err < 0)) - goto freedreamcast; - /* Register the card with ALSA subsystem */ - err = snd_card_register(dreamcastcard->card); - if (unlikely(err < 0)) - goto freedreamcast; - platform_set_drvdata(devptr, dreamcastcard); - snd_printk - ("ALSA Driver for Yamaha AICA Super Intelligent Sound Processor\n"); - return 0; - freedreamcast: - snd_card_free(dreamcastcard->card); - kfree(dreamcastcard); - return err; -} - -static struct platform_driver snd_aica_driver = { - .probe = snd_aica_probe, - .remove = snd_aica_remove, - .driver = { - .name = SND_AICA_DRIVER, - }, -}; - -static int __init aica_init(void) -{ - int err; - err = platform_driver_register(&snd_aica_driver); - if (unlikely(err < 0)) - return err; - pd = platform_device_register_simple(SND_AICA_DRIVER, -1, - aica_memory_space, 2); - if (IS_ERR(pd)) { - platform_driver_unregister(&snd_aica_driver); - return PTR_ERR(pd); - } - /* Load the firmware */ - return load_aica_firmware(); -} - -static void __exit aica_exit(void) -{ - platform_device_unregister(pd); - platform_driver_unregister(&snd_aica_driver); - /* Kill any sound still playing and reset ARM7 to safe state */ - spu_reset(); -} - -module_init(aica_init); -module_exit(aica_exit); diff --git a/sound/sh/aica.h b/sound/sh/aica.h deleted file mode 100644 index 021b132e088e82..00000000000000 --- a/sound/sh/aica.h +++ /dev/null @@ -1,68 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* aica.h - * Header file for ALSA driver for - * Sega Dreamcast Yamaha AICA sound - * Copyright Adrian McMenamin - * - * 2006 - */ - -/* SPU memory and register constants etc */ -#define G2_FIFO 0xa05f688c -#define SPU_MEMORY_BASE 0xA0800000 -#define ARM_RESET_REGISTER 0xA0702C00 -#define SPU_REGISTER_BASE 0xA0700000 - -/* AICA channels stuff */ -#define AICA_CONTROL_POINT 0xA0810000 -#define AICA_CONTROL_CHANNEL_SAMPLE_NUMBER 0xA0810008 -#define AICA_CHANNEL0_CONTROL_OFFSET 0x10004 - -/* Command values */ -#define AICA_CMD_KICK 0x80000000 -#define AICA_CMD_NONE 0 -#define AICA_CMD_START 1 -#define AICA_CMD_STOP 2 -#define AICA_CMD_VOL 3 - -/* Sound modes */ -#define SM_8BIT 1 -#define SM_16BIT 0 -#define SM_ADPCM 2 - -/* Buffer and period size */ -#define AICA_BUFFER_SIZE 0x8000 -#define AICA_PERIOD_SIZE 0x800 -#define AICA_PERIOD_NUMBER 16 - -#define AICA_CHANNEL0_OFFSET 0x11000 -#define AICA_CHANNEL1_OFFSET 0x21000 -#define CHANNEL_OFFSET 0x10000 - -#define AICA_DMA_CHANNEL 5 -#define AICA_DMA_MODE 5 - -#define SND_AICA_DRIVER "AICA" - -struct aica_channel { - uint32_t cmd; /* Command ID */ - uint32_t pos; /* Sample position */ - uint32_t length; /* Sample length */ - uint32_t freq; /* Frequency */ - uint32_t vol; /* Volume 0-255 */ - uint32_t pan; /* Pan 0-255 */ - uint32_t sfmt; /* Sound format */ - uint32_t flags; /* Bit flags */ -}; - -struct snd_card_aica { - struct work_struct spu_dma_work; - struct snd_card *card; - struct aica_channel *channel; - struct snd_pcm_substream *substream; - int clicks; - int current_period; - struct timer_list timer; - int master_volume; - int dma_check; -}; diff --git a/sound/sh/sh_dac_audio.c b/sound/sh/sh_dac_audio.c deleted file mode 100644 index 8ebd972846acb5..00000000000000 --- a/sound/sh/sh_dac_audio.c +++ /dev/null @@ -1,412 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * sh_dac_audio.c - SuperH DAC audio driver for ALSA - * - * Copyright (c) 2009 by Rafael Ignacio Zurita - * - * Based on sh_dac_audio.c (Copyright (C) 2004, 2005 by Andriy Skulysh) - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Rafael Ignacio Zurita "); -MODULE_DESCRIPTION("SuperH DAC audio driver"); -MODULE_LICENSE("GPL"); - -/* Module Parameters */ -static int index = SNDRV_DEFAULT_IDX1; -static char *id = SNDRV_DEFAULT_STR1; -module_param(index, int, 0444); -MODULE_PARM_DESC(index, "Index value for SuperH DAC audio."); -module_param(id, charp, 0444); -MODULE_PARM_DESC(id, "ID string for SuperH DAC audio."); - -/* main struct */ -struct snd_sh_dac { - struct snd_card *card; - struct snd_pcm_substream *substream; - struct hrtimer hrtimer; - ktime_t wakeups_per_second; - - int rate; - int empty; - char *data_buffer, *buffer_begin, *buffer_end; - int processed; /* bytes proccesed, to compare with period_size */ - int buffer_size; - struct dac_audio_pdata *pdata; -}; - - -static void dac_audio_start_timer(struct snd_sh_dac *chip) -{ - hrtimer_start(&chip->hrtimer, chip->wakeups_per_second, - HRTIMER_MODE_REL); -} - -static void dac_audio_stop_timer(struct snd_sh_dac *chip) -{ - hrtimer_cancel(&chip->hrtimer); -} - -static void dac_audio_reset(struct snd_sh_dac *chip) -{ - dac_audio_stop_timer(chip); - chip->buffer_begin = chip->buffer_end = chip->data_buffer; - chip->processed = 0; - chip->empty = 1; -} - -static void dac_audio_set_rate(struct snd_sh_dac *chip) -{ - chip->wakeups_per_second = 1000000000 / chip->rate; -} - - -/* PCM INTERFACE */ - -static const struct snd_pcm_hardware snd_sh_dac_pcm_hw = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_HALF_DUPLEX), - .formats = SNDRV_PCM_FMTBIT_U8, - .rates = SNDRV_PCM_RATE_8000, - .rate_min = 8000, - .rate_max = 8000, - .channels_min = 1, - .channels_max = 1, - .buffer_bytes_max = (48*1024), - .period_bytes_min = 1, - .period_bytes_max = (48*1024), - .periods_min = 1, - .periods_max = 1024, -}; - -static int snd_sh_dac_pcm_open(struct snd_pcm_substream *substream) -{ - struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = substream->runtime; - - runtime->hw = snd_sh_dac_pcm_hw; - - chip->substream = substream; - chip->buffer_begin = chip->buffer_end = chip->data_buffer; - chip->processed = 0; - chip->empty = 1; - - chip->pdata->start(chip->pdata); - - return 0; -} - -static int snd_sh_dac_pcm_close(struct snd_pcm_substream *substream) -{ - struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - - chip->substream = NULL; - - dac_audio_stop_timer(chip); - chip->pdata->stop(chip->pdata); - - return 0; -} - -static int snd_sh_dac_pcm_prepare(struct snd_pcm_substream *substream) -{ - struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - struct snd_pcm_runtime *runtime = chip->substream->runtime; - - chip->buffer_size = runtime->buffer_size; - memset(chip->data_buffer, 0, chip->pdata->buffer_size); - - return 0; -} - -static int snd_sh_dac_pcm_trigger(struct snd_pcm_substream *substream, int cmd) -{ - struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - dac_audio_start_timer(chip); - break; - case SNDRV_PCM_TRIGGER_STOP: - chip->buffer_begin = chip->buffer_end = chip->data_buffer; - chip->processed = 0; - chip->empty = 1; - dac_audio_stop_timer(chip); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int snd_sh_dac_pcm_copy(struct snd_pcm_substream *substream, - int channel, unsigned long pos, - void __user *src, unsigned long count) -{ - /* channel is not used (interleaved data) */ - struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - - if (copy_from_user_toio(chip->data_buffer + pos, src, count)) - return -EFAULT; - chip->buffer_end = chip->data_buffer + pos + count; - - if (chip->empty) { - chip->empty = 0; - dac_audio_start_timer(chip); - } - - return 0; -} - -static int snd_sh_dac_pcm_copy_kernel(struct snd_pcm_substream *substream, - int channel, unsigned long pos, - void *src, unsigned long count) -{ - /* channel is not used (interleaved data) */ - struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - - memcpy_toio(chip->data_buffer + pos, src, count); - chip->buffer_end = chip->data_buffer + pos + count; - - if (chip->empty) { - chip->empty = 0; - dac_audio_start_timer(chip); - } - - return 0; -} - -static int snd_sh_dac_pcm_silence(struct snd_pcm_substream *substream, - int channel, unsigned long pos, - unsigned long count) -{ - /* channel is not used (interleaved data) */ - struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - - memset_io(chip->data_buffer + pos, 0, count); - chip->buffer_end = chip->data_buffer + pos + count; - - if (chip->empty) { - chip->empty = 0; - dac_audio_start_timer(chip); - } - - return 0; -} - -static -snd_pcm_uframes_t snd_sh_dac_pcm_pointer(struct snd_pcm_substream *substream) -{ - struct snd_sh_dac *chip = snd_pcm_substream_chip(substream); - int pointer = chip->buffer_begin - chip->data_buffer; - - return pointer; -} - -/* pcm ops */ -static const struct snd_pcm_ops snd_sh_dac_pcm_ops = { - .open = snd_sh_dac_pcm_open, - .close = snd_sh_dac_pcm_close, - .prepare = snd_sh_dac_pcm_prepare, - .trigger = snd_sh_dac_pcm_trigger, - .pointer = snd_sh_dac_pcm_pointer, - .copy_user = snd_sh_dac_pcm_copy, - .copy_kernel = snd_sh_dac_pcm_copy_kernel, - .fill_silence = snd_sh_dac_pcm_silence, - .mmap = snd_pcm_lib_mmap_iomem, -}; - -static int snd_sh_dac_pcm(struct snd_sh_dac *chip, int device) -{ - int err; - struct snd_pcm *pcm; - - /* device should be always 0 for us */ - err = snd_pcm_new(chip->card, "SH_DAC PCM", device, 1, 0, &pcm); - if (err < 0) - return err; - - pcm->private_data = chip; - strcpy(pcm->name, "SH_DAC PCM"); - snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sh_dac_pcm_ops); - - /* buffer size=48K */ - snd_pcm_set_managed_buffer_all(pcm, SNDRV_DMA_TYPE_CONTINUOUS, - NULL, 48 * 1024, 48 * 1024); - - return 0; -} -/* END OF PCM INTERFACE */ - - -/* driver .remove -- destructor */ -static int snd_sh_dac_remove(struct platform_device *devptr) -{ - snd_card_free(platform_get_drvdata(devptr)); - return 0; -} - -/* free -- it has been defined by create */ -static int snd_sh_dac_free(struct snd_sh_dac *chip) -{ - /* release the data */ - kfree(chip->data_buffer); - kfree(chip); - - return 0; -} - -static int snd_sh_dac_dev_free(struct snd_device *device) -{ - struct snd_sh_dac *chip = device->device_data; - - return snd_sh_dac_free(chip); -} - -static enum hrtimer_restart sh_dac_audio_timer(struct hrtimer *handle) -{ - struct snd_sh_dac *chip = container_of(handle, struct snd_sh_dac, - hrtimer); - struct snd_pcm_runtime *runtime = chip->substream->runtime; - ssize_t b_ps = frames_to_bytes(runtime, runtime->period_size); - - if (!chip->empty) { - sh_dac_output(*chip->buffer_begin, chip->pdata->channel); - chip->buffer_begin++; - - chip->processed++; - if (chip->processed >= b_ps) { - chip->processed -= b_ps; - snd_pcm_period_elapsed(chip->substream); - } - - if (chip->buffer_begin == (chip->data_buffer + - chip->buffer_size - 1)) - chip->buffer_begin = chip->data_buffer; - - if (chip->buffer_begin == chip->buffer_end) - chip->empty = 1; - - } - - if (!chip->empty) - hrtimer_start(&chip->hrtimer, chip->wakeups_per_second, - HRTIMER_MODE_REL); - - return HRTIMER_NORESTART; -} - -/* create -- chip-specific constructor for the cards components */ -static int snd_sh_dac_create(struct snd_card *card, - struct platform_device *devptr, - struct snd_sh_dac **rchip) -{ - struct snd_sh_dac *chip; - int err; - - static const struct snd_device_ops ops = { - .dev_free = snd_sh_dac_dev_free, - }; - - *rchip = NULL; - - chip = kzalloc(sizeof(*chip), GFP_KERNEL); - if (chip == NULL) - return -ENOMEM; - - chip->card = card; - - hrtimer_init(&chip->hrtimer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); - chip->hrtimer.function = sh_dac_audio_timer; - - dac_audio_reset(chip); - chip->rate = 8000; - dac_audio_set_rate(chip); - - chip->pdata = devptr->dev.platform_data; - - chip->data_buffer = kmalloc(chip->pdata->buffer_size, GFP_KERNEL); - if (chip->data_buffer == NULL) { - kfree(chip); - return -ENOMEM; - } - - err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); - if (err < 0) { - snd_sh_dac_free(chip); - return err; - } - - *rchip = chip; - - return 0; -} - -/* driver .probe -- constructor */ -static int snd_sh_dac_probe(struct platform_device *devptr) -{ - struct snd_sh_dac *chip; - struct snd_card *card; - int err; - - err = snd_card_new(&devptr->dev, index, id, THIS_MODULE, 0, &card); - if (err < 0) { - snd_printk(KERN_ERR "cannot allocate the card\n"); - return err; - } - - err = snd_sh_dac_create(card, devptr, &chip); - if (err < 0) - goto probe_error; - - err = snd_sh_dac_pcm(chip, 0); - if (err < 0) - goto probe_error; - - strcpy(card->driver, "snd_sh_dac"); - strcpy(card->shortname, "SuperH DAC audio driver"); - printk(KERN_INFO "%s %s", card->longname, card->shortname); - - err = snd_card_register(card); - if (err < 0) - goto probe_error; - - snd_printk(KERN_INFO "ALSA driver for SuperH DAC audio"); - - platform_set_drvdata(devptr, card); - return 0; - -probe_error: - snd_card_free(card); - return err; -} - -/* - * "driver" definition - */ -static struct platform_driver sh_dac_driver = { - .probe = snd_sh_dac_probe, - .remove = snd_sh_dac_remove, - .driver = { - .name = "dac_audio", - }, -}; - -module_platform_driver(sh_dac_driver); From patchwork Fri Jan 13 06:23:22 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642274 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1ED52C61DB3 for ; Fri, 13 Jan 2023 06:26:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235363AbjAMGZ4 (ORCPT ); Fri, 13 Jan 2023 01:25:56 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33408 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234761AbjAMGYg (ORCPT ); Fri, 13 Jan 2023 01:24:36 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 498495C1E9; Thu, 12 Jan 2023 22:24:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=erzrm4Ty5idHGyu1jH564OsyzlBO2Da+dsAYs2Uai6g=; b=PetC+G54fA2MHOPn5yey+DdmCl R14MH27shd3orjHYKWEFGSdK5sHDVqWEit9ROBI9QtItF8PeoTYlNLc27qCKd4mBlGl8jANIltvc4 5uvf/bF6LMZMC3fRULQGtDiirUzaHq9DinFdafA4frKBNm+yAMh94U6OnJ7LGL0XptNiPpS5DsIWd GO3TjAdGZQt0xM+O6jEYTtFY/OIcQA9dsgy6SBP+X4K3WFPlg8cv17nlZY99em0nT73cU9pNa99ua b3uzExO4rYmov4NBJ22hBeTV6aNAU0ZwIK9zJ00YufRoOb+tROzO9aXzsvT/iQZ6VeSKM1biDvQti x8bvB2Pg==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDTu-000lTC-Dy; Fri, 13 Jan 2023 06:24:04 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 05/22] sound: remove sh-specific sounds/soc/sh drivers Date: Fri, 13 Jan 2023 07:23:22 +0100 Message-Id: <20230113062339.1909087-6-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that arch/sh is removed these drivers are dead code. Signed-off-by: Christoph Hellwig --- sound/soc/sh/Kconfig | 44 -- sound/soc/sh/Makefile | 16 - sound/soc/sh/dma-sh7760.c | 334 ---------------- sound/soc/sh/fsi.c | 9 - sound/soc/sh/hac.c | 345 ---------------- sound/soc/sh/migor.c | 205 ---------- sound/soc/sh/sh7760-ac97.c | 72 ---- sound/soc/sh/siu.h | 180 --------- sound/soc/sh/siu_dai.c | 799 ------------------------------------- sound/soc/sh/siu_pcm.c | 553 ------------------------- sound/soc/sh/ssi.c | 403 ------------------- 11 files changed, 2960 deletions(-) delete mode 100644 sound/soc/sh/dma-sh7760.c delete mode 100644 sound/soc/sh/hac.c delete mode 100644 sound/soc/sh/migor.c delete mode 100644 sound/soc/sh/sh7760-ac97.c delete mode 100644 sound/soc/sh/siu.h delete mode 100644 sound/soc/sh/siu_dai.c delete mode 100644 sound/soc/sh/siu_pcm.c delete mode 100644 sound/soc/sh/ssi.c diff --git a/sound/soc/sh/Kconfig b/sound/soc/sh/Kconfig index 793a0326f32b46..4367927b81df20 100644 --- a/sound/soc/sh/Kconfig +++ b/sound/soc/sh/Kconfig @@ -2,25 +2,10 @@ menu "SoC Audio support for Renesas SoCs" depends on ARCH_RENESAS || COMPILE_TEST -config SND_SOC_PCM_SH7760 - tristate "SoC Audio support for Renesas SH7760" - depends on CPU_SUBTYPE_SH7760 && SH_DMABRG - help - Enable this option for SH7760 AC97/I2S audio support. - - ## ## Audio unit modules ## -config SND_SOC_SH4_HAC - tristate - select AC97_BUS - select SND_SOC_AC97_BUS - -config SND_SOC_SH4_SSI - tristate - config SND_SOC_SH4_FSI tristate "SH4 FSI support" depends on COMMON_CLK @@ -28,14 +13,6 @@ config SND_SOC_SH4_FSI help This option enables FSI sound support -config SND_SOC_SH4_SIU - tristate - depends on ARCH_SHMOBILE && HAVE_CLK - depends on DMADEVICES - select DMA_ENGINE - select SH_DMAE - select FW_LOADER - config SND_SOC_RCAR tristate "R-Car series SRU/SCU/SSIU/SSI support" depends on COMMON_CLK @@ -51,25 +28,4 @@ config SND_SOC_RZ help This option enables RZ/G2L SSIF-2 sound support. -## -## Boards -## - -config SND_SH7760_AC97 - tristate "SH7760 AC97 sound support" - depends on CPU_SUBTYPE_SH7760 && SND_SOC_PCM_SH7760 - select SND_SOC_SH4_HAC - select SND_SOC_AC97_CODEC - help - This option enables generic sound support for the first - AC97 unit of the SH7760. - -config SND_SIU_MIGOR - tristate "SIU sound support on Migo-R" - depends on SH_MIGOR && I2C - select SND_SOC_SH4_SIU - select SND_SOC_WM8978 - help - This option enables sound support for the SH7722 Migo-R board - endmenu diff --git a/sound/soc/sh/Makefile b/sound/soc/sh/Makefile index f6fd79948f6ae9..c308dda887e633 100644 --- a/sound/soc/sh/Makefile +++ b/sound/soc/sh/Makefile @@ -1,28 +1,12 @@ # SPDX-License-Identifier: GPL-2.0 -## DMA engines -snd-soc-dma-sh7760-objs := dma-sh7760.o -obj-$(CONFIG_SND_SOC_PCM_SH7760) += snd-soc-dma-sh7760.o ## audio units found on some SH-4 -snd-soc-hac-objs := hac.o -snd-soc-ssi-objs := ssi.o snd-soc-fsi-objs := fsi.o -snd-soc-siu-objs := siu_pcm.o siu_dai.o -obj-$(CONFIG_SND_SOC_SH4_HAC) += snd-soc-hac.o -obj-$(CONFIG_SND_SOC_SH4_SSI) += snd-soc-ssi.o obj-$(CONFIG_SND_SOC_SH4_FSI) += snd-soc-fsi.o -obj-$(CONFIG_SND_SOC_SH4_SIU) += snd-soc-siu.o ## audio units for R-Car obj-$(CONFIG_SND_SOC_RCAR) += rcar/ -## boards -snd-soc-sh7760-ac97-objs := sh7760-ac97.o -snd-soc-migor-objs := migor.o - -obj-$(CONFIG_SND_SH7760_AC97) += snd-soc-sh7760-ac97.o -obj-$(CONFIG_SND_SIU_MIGOR) += snd-soc-migor.o - # RZ/G2L snd-soc-rz-ssi-objs := rz-ssi.o obj-$(CONFIG_SND_SOC_RZ) += snd-soc-rz-ssi.o diff --git a/sound/soc/sh/dma-sh7760.c b/sound/soc/sh/dma-sh7760.c deleted file mode 100644 index 121e48f984c50c..00000000000000 --- a/sound/soc/sh/dma-sh7760.c +++ /dev/null @@ -1,334 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// SH7760 ("camelot") DMABRG audio DMA unit support -// -// Copyright (C) 2007 Manuel Lauss -// -// The SH7760 DMABRG provides 4 dma channels (2x rec, 2x play), which -// trigger an interrupt when one half of the programmed transfer size -// has been xmitted. -// -// FIXME: little-endian only for now - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -/* registers and bits */ -#define BRGATXSAR 0x00 -#define BRGARXDAR 0x04 -#define BRGATXTCR 0x08 -#define BRGARXTCR 0x0C -#define BRGACR 0x10 -#define BRGATXTCNT 0x14 -#define BRGARXTCNT 0x18 - -#define ACR_RAR (1 << 18) -#define ACR_RDS (1 << 17) -#define ACR_RDE (1 << 16) -#define ACR_TAR (1 << 2) -#define ACR_TDS (1 << 1) -#define ACR_TDE (1 << 0) - -/* receiver/transmitter data alignment */ -#define ACR_RAM_NONE (0 << 24) -#define ACR_RAM_4BYTE (1 << 24) -#define ACR_RAM_2WORD (2 << 24) -#define ACR_TAM_NONE (0 << 8) -#define ACR_TAM_4BYTE (1 << 8) -#define ACR_TAM_2WORD (2 << 8) - - -struct camelot_pcm { - unsigned long mmio; /* DMABRG audio channel control reg MMIO */ - unsigned int txid; /* ID of first DMABRG IRQ for this unit */ - - struct snd_pcm_substream *tx_ss; - unsigned long tx_period_size; - unsigned int tx_period; - - struct snd_pcm_substream *rx_ss; - unsigned long rx_period_size; - unsigned int rx_period; - -} cam_pcm_data[2] = { - { - .mmio = 0xFE3C0040, - .txid = DMABRGIRQ_A0TXF, - }, - { - .mmio = 0xFE3C0060, - .txid = DMABRGIRQ_A1TXF, - }, -}; - -#define BRGREG(x) (*(unsigned long *)(cam->mmio + (x))) - -/* - * set a minimum of 16kb per period, to avoid interrupt-"storm" and - * resulting skipping. In general, the bigger the minimum size, the - * better for overall system performance. (The SH7760 is a puny CPU - * with a slow SDRAM interface and poor internal bus bandwidth, - * *especially* when the LCDC is active). The minimum for the DMAC - * is 8 bytes; 16kbytes are enough to get skip-free playback of a - * 44kHz/16bit/stereo MP3 on a lightly loaded system, and maintain - * reasonable responsiveness in MPlayer. - */ -#define DMABRG_PERIOD_MIN 16 * 1024 -#define DMABRG_PERIOD_MAX 0x03fffffc -#define DMABRG_PREALLOC_BUFFER 32 * 1024 -#define DMABRG_PREALLOC_BUFFER_MAX 32 * 1024 - -static const struct snd_pcm_hardware camelot_pcm_hardware = { - .info = (SNDRV_PCM_INFO_MMAP | - SNDRV_PCM_INFO_INTERLEAVED | - SNDRV_PCM_INFO_BLOCK_TRANSFER | - SNDRV_PCM_INFO_MMAP_VALID | - SNDRV_PCM_INFO_BATCH), - .buffer_bytes_max = DMABRG_PERIOD_MAX, - .period_bytes_min = DMABRG_PERIOD_MIN, - .period_bytes_max = DMABRG_PERIOD_MAX / 2, - .periods_min = 2, - .periods_max = 2, - .fifo_size = 128, -}; - -static void camelot_txdma(void *data) -{ - struct camelot_pcm *cam = data; - cam->tx_period ^= 1; - snd_pcm_period_elapsed(cam->tx_ss); -} - -static void camelot_rxdma(void *data) -{ - struct camelot_pcm *cam = data; - cam->rx_period ^= 1; - snd_pcm_period_elapsed(cam->rx_ss); -} - -static int camelot_pcm_open(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int ret, dmairq; - - snd_soc_set_runtime_hwparams(substream, &camelot_pcm_hardware); - - /* DMABRG buffer half/full events */ - dmairq = (recv) ? cam->txid + 2 : cam->txid; - if (recv) { - cam->rx_ss = substream; - ret = dmabrg_request_irq(dmairq, camelot_rxdma, cam); - if (unlikely(ret)) { - pr_debug("audio unit %d irqs already taken!\n", - asoc_rtd_to_cpu(rtd, 0)->id); - return -EBUSY; - } - (void)dmabrg_request_irq(dmairq + 1,camelot_rxdma, cam); - } else { - cam->tx_ss = substream; - ret = dmabrg_request_irq(dmairq, camelot_txdma, cam); - if (unlikely(ret)) { - pr_debug("audio unit %d irqs already taken!\n", - asoc_rtd_to_cpu(rtd, 0)->id); - return -EBUSY; - } - (void)dmabrg_request_irq(dmairq + 1, camelot_txdma, cam); - } - return 0; -} - -static int camelot_pcm_close(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - int dmairq; - - dmairq = (recv) ? cam->txid + 2 : cam->txid; - - if (recv) - cam->rx_ss = NULL; - else - cam->tx_ss = NULL; - - dmabrg_free_irq(dmairq + 1); - dmabrg_free_irq(dmairq); - - return 0; -} - -static int camelot_hw_params(struct snd_soc_component *component, - struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *hw_params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - - if (recv) { - cam->rx_period_size = params_period_bytes(hw_params); - cam->rx_period = 0; - } else { - cam->tx_period_size = params_period_bytes(hw_params); - cam->tx_period = 0; - } - return 0; -} - -static int camelot_prepare(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - - pr_debug("PCM data: addr 0x%08lx len %d\n", - (u32)runtime->dma_addr, runtime->dma_bytes); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - BRGREG(BRGATXSAR) = (unsigned long)runtime->dma_area; - BRGREG(BRGATXTCR) = runtime->dma_bytes; - } else { - BRGREG(BRGARXDAR) = (unsigned long)runtime->dma_area; - BRGREG(BRGARXTCR) = runtime->dma_bytes; - } - - return 0; -} - -static inline void dmabrg_play_dma_start(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* start DMABRG engine: XFER start, auto-addr-reload */ - BRGREG(BRGACR) = acr | ACR_TDE | ACR_TAR | ACR_TAM_2WORD; -} - -static inline void dmabrg_play_dma_stop(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* forcibly terminate data transmission */ - BRGREG(BRGACR) = acr | ACR_TDS; -} - -static inline void dmabrg_rec_dma_start(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* start DMABRG engine: recv start, auto-reload */ - BRGREG(BRGACR) = acr | ACR_RDE | ACR_RAR | ACR_RAM_2WORD; -} - -static inline void dmabrg_rec_dma_stop(struct camelot_pcm *cam) -{ - unsigned long acr = BRGREG(BRGACR) & ~(ACR_TDS | ACR_RDS); - /* forcibly terminate data receiver */ - BRGREG(BRGACR) = acr | ACR_RDS; -} - -static int camelot_trigger(struct snd_soc_component *component, - struct snd_pcm_substream *substream, int cmd) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (recv) - dmabrg_rec_dma_start(cam); - else - dmabrg_play_dma_start(cam); - break; - case SNDRV_PCM_TRIGGER_STOP: - if (recv) - dmabrg_rec_dma_stop(cam); - else - dmabrg_play_dma_stop(cam); - break; - default: - return -EINVAL; - } - - return 0; -} - -static snd_pcm_uframes_t camelot_pos(struct snd_soc_component *component, - struct snd_pcm_substream *substream) -{ - struct snd_pcm_runtime *runtime = substream->runtime; - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct camelot_pcm *cam = &cam_pcm_data[asoc_rtd_to_cpu(rtd, 0)->id]; - int recv = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0:1; - unsigned long pos; - - /* cannot use the DMABRG pointer register: under load, by the - * time ALSA comes around to read the register, it is already - * far ahead (or worse, already done with the fragment) of the - * position at the time the IRQ was triggered, which results in - * fast-playback sound in my test application (ScummVM) - */ - if (recv) - pos = cam->rx_period ? cam->rx_period_size : 0; - else - pos = cam->tx_period ? cam->tx_period_size : 0; - - return bytes_to_frames(runtime, pos); -} - -static int camelot_pcm_new(struct snd_soc_component *component, - struct snd_soc_pcm_runtime *rtd) -{ - struct snd_pcm *pcm = rtd->pcm; - - /* dont use SNDRV_DMA_TYPE_DEV, since it will oops the SH kernel - * in MMAP mode (i.e. aplay -M) - */ - snd_pcm_set_managed_buffer_all(pcm, - SNDRV_DMA_TYPE_CONTINUOUS, - NULL, - DMABRG_PREALLOC_BUFFER, DMABRG_PREALLOC_BUFFER_MAX); - - return 0; -} - -static const struct snd_soc_component_driver sh7760_soc_component = { - .open = camelot_pcm_open, - .close = camelot_pcm_close, - .hw_params = camelot_hw_params, - .prepare = camelot_prepare, - .trigger = camelot_trigger, - .pointer = camelot_pos, - .pcm_construct = camelot_pcm_new, -}; - -static int sh7760_soc_platform_probe(struct platform_device *pdev) -{ - return devm_snd_soc_register_component(&pdev->dev, &sh7760_soc_component, - NULL, 0); -} - -static struct platform_driver sh7760_pcm_driver = { - .driver = { - .name = "sh7760-pcm-audio", - }, - - .probe = sh7760_soc_platform_probe, -}; - -module_platform_driver(sh7760_pcm_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("SH7760 Audio DMA (DMABRG) driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c index f3edc2e3d9d7c4..c599070f2210f4 100644 --- a/sound/soc/sh/fsi.c +++ b/sound/soc/sh/fsi.c @@ -1372,16 +1372,7 @@ static int fsi_dma_probe(struct fsi_priv *fsi, struct fsi_stream *io, struct dev { int is_play = fsi_stream_is_play(fsi, io); -#ifdef CONFIG_SUPERH - dma_cap_mask_t mask; - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - io->chan = dma_request_channel(mask, shdma_chan_filter, - (void *)io->dma_id); -#else io->chan = dma_request_slave_channel(dev, is_play ? "tx" : "rx"); -#endif if (io->chan) { struct dma_slave_config cfg = {}; int ret; diff --git a/sound/soc/sh/hac.c b/sound/soc/sh/hac.c deleted file mode 100644 index 46d145cbaf2970..00000000000000 --- a/sound/soc/sh/hac.c +++ /dev/null @@ -1,345 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Hitachi Audio Controller (AC97) support for SH7760/SH7780 -// -// Copyright (c) 2007 Manuel Lauss -// -// dont forget to set IPSEL/OMSEL register bits (in your board code) to -// enable HAC output pins! - -/* BIG FAT FIXME: although the SH7760 has 2 independent AC97 units, only - * the FIRST can be used since ASoC does not pass any information to the - * ac97_read/write() functions regarding WHICH unit to use. You'll have - * to edit the code a bit to use the other AC97 unit. --mlau - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* regs and bits */ -#define HACCR 0x08 -#define HACCSAR 0x20 -#define HACCSDR 0x24 -#define HACPCML 0x28 -#define HACPCMR 0x2C -#define HACTIER 0x50 -#define HACTSR 0x54 -#define HACRIER 0x58 -#define HACRSR 0x5C -#define HACACR 0x60 - -#define CR_CR (1 << 15) /* "codec-ready" indicator */ -#define CR_CDRT (1 << 11) /* cold reset */ -#define CR_WMRT (1 << 10) /* warm reset */ -#define CR_B9 (1 << 9) /* the mysterious "bit 9" */ -#define CR_ST (1 << 5) /* AC97 link start bit */ - -#define CSAR_RD (1 << 19) /* AC97 data read bit */ -#define CSAR_WR (0) - -#define TSR_CMDAMT (1 << 31) -#define TSR_CMDDMT (1 << 30) - -#define RSR_STARY (1 << 22) -#define RSR_STDRY (1 << 21) - -#define ACR_DMARX16 (1 << 30) -#define ACR_DMATX16 (1 << 29) -#define ACR_TX12ATOM (1 << 26) -#define ACR_DMARX20 ((1 << 24) | (1 << 22)) -#define ACR_DMATX20 ((1 << 23) | (1 << 21)) - -#define CSDR_SHIFT 4 -#define CSDR_MASK (0xffff << CSDR_SHIFT) -#define CSAR_SHIFT 12 -#define CSAR_MASK (0x7f << CSAR_SHIFT) - -#define AC97_WRITE_RETRY 1 -#define AC97_READ_RETRY 5 - -/* manual-suggested AC97 codec access timeouts (us) */ -#define TMO_E1 500 /* 21 < E1 < 1000 */ -#define TMO_E2 13 /* 13 < E2 */ -#define TMO_E3 21 /* 21 < E3 */ -#define TMO_E4 500 /* 21 < E4 < 1000 */ - -struct hac_priv { - unsigned long mmio; /* HAC base address */ -} hac_cpu_data[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - { - .mmio = 0xFE240000, - }, - { - .mmio = 0xFE250000, - }, -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { - .mmio = 0xFFE40000, - }, -#else -#error "Unsupported SuperH SoC" -#endif -}; - -#define HACREG(reg) (*(unsigned long *)(hac->mmio + (reg))) - -/* - * AC97 read/write flow as outlined in the SH7760 manual (pages 903-906) - */ -static int hac_get_codec_data(struct hac_priv *hac, unsigned short r, - unsigned short *v) -{ - unsigned int to1, to2, i; - unsigned short adr; - - for (i = AC97_READ_RETRY; i; i--) { - *v = 0; - /* wait for HAC to receive something from the codec */ - for (to1 = TMO_E4; - to1 && !(HACREG(HACRSR) & RSR_STARY); - --to1) - udelay(1); - for (to2 = TMO_E4; - to2 && !(HACREG(HACRSR) & RSR_STDRY); - --to2) - udelay(1); - - if (!to1 && !to2) - return 0; /* codec comm is down */ - - adr = ((HACREG(HACCSAR) & CSAR_MASK) >> CSAR_SHIFT); - *v = ((HACREG(HACCSDR) & CSDR_MASK) >> CSDR_SHIFT); - - HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); - - if (r == adr) - break; - - /* manual says: wait at least 21 usec before retrying */ - udelay(21); - } - HACREG(HACRSR) &= ~(RSR_STDRY | RSR_STARY); - return i; -} - -static unsigned short hac_read_codec_aux(struct hac_priv *hac, - unsigned short reg) -{ - unsigned short val; - unsigned int i, to; - - for (i = AC97_READ_RETRY; i; i--) { - /* send_read_request */ - local_irq_disable(); - HACREG(HACTSR) &= ~(TSR_CMDAMT); - HACREG(HACCSAR) = (reg << CSAR_SHIFT) | CSAR_RD; - local_irq_enable(); - - for (to = TMO_E3; - to && !(HACREG(HACTSR) & TSR_CMDAMT); - --to) - udelay(1); - - HACREG(HACTSR) &= ~TSR_CMDAMT; - val = 0; - if (hac_get_codec_data(hac, reg, &val) != 0) - break; - } - - return i ? val : ~0; -} - -static void hac_ac97_write(struct snd_ac97 *ac97, unsigned short reg, - unsigned short val) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - unsigned int i, to; - /* write_codec_aux */ - for (i = AC97_WRITE_RETRY; i; i--) { - /* send_write_request */ - local_irq_disable(); - HACREG(HACTSR) &= ~(TSR_CMDDMT | TSR_CMDAMT); - HACREG(HACCSDR) = (val << CSDR_SHIFT); - HACREG(HACCSAR) = (reg << CSAR_SHIFT) & (~CSAR_RD); - local_irq_enable(); - - /* poll-wait for CMDAMT and CMDDMT */ - for (to = TMO_E1; - to && !(HACREG(HACTSR) & (TSR_CMDAMT|TSR_CMDDMT)); - --to) - udelay(1); - - HACREG(HACTSR) &= ~(TSR_CMDAMT | TSR_CMDDMT); - if (to) - break; - /* timeout, try again */ - } -} - -static unsigned short hac_ac97_read(struct snd_ac97 *ac97, - unsigned short reg) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - return hac_read_codec_aux(hac, reg); -} - -static void hac_ac97_warmrst(struct snd_ac97 *ac97) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac = &hac_cpu_data[unit_id]; - unsigned int tmo; - - HACREG(HACCR) = CR_WMRT | CR_ST | CR_B9; - msleep(10); - HACREG(HACCR) = CR_ST | CR_B9; - for (tmo = 1000; (tmo > 0) && !(HACREG(HACCR) & CR_CR); tmo--) - udelay(1); - - if (!tmo) - printk(KERN_INFO "hac: reset: AC97 link down!\n"); - /* settings this bit lets us have a conversation with codec */ - HACREG(HACACR) |= ACR_TX12ATOM; -} - -static void hac_ac97_coldrst(struct snd_ac97 *ac97) -{ - int unit_id = 0 /* ac97->private_data */; - struct hac_priv *hac; - hac = &hac_cpu_data[unit_id]; - - HACREG(HACCR) = 0; - HACREG(HACCR) = CR_CDRT | CR_ST | CR_B9; - msleep(10); - hac_ac97_warmrst(ac97); -} - -static struct snd_ac97_bus_ops hac_ac97_ops = { - .read = hac_ac97_read, - .write = hac_ac97_write, - .reset = hac_ac97_coldrst, - .warm_reset = hac_ac97_warmrst, -}; - -static int hac_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct hac_priv *hac = &hac_cpu_data[dai->id]; - int d = substream->stream == SNDRV_PCM_STREAM_PLAYBACK ? 0 : 1; - - switch (params->msbits) { - case 16: - HACREG(HACACR) |= d ? ACR_DMARX16 : ACR_DMATX16; - HACREG(HACACR) &= d ? ~ACR_DMARX20 : ~ACR_DMATX20; - break; - case 20: - HACREG(HACACR) &= d ? ~ACR_DMARX16 : ~ACR_DMATX16; - HACREG(HACACR) |= d ? ACR_DMARX20 : ACR_DMATX20; - break; - default: - pr_debug("hac: invalid depth %d bit\n", params->msbits); - return -EINVAL; - break; - } - - return 0; -} - -#define AC97_RATES \ - SNDRV_PCM_RATE_8000_192000 - -#define AC97_FMTS \ - SNDRV_PCM_FMTBIT_S16_LE - -static const struct snd_soc_dai_ops hac_dai_ops = { - .hw_params = hac_hw_params, -}; - -static struct snd_soc_dai_driver sh4_hac_dai[] = { -{ - .name = "hac-dai.0", - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .ops = &hac_dai_ops, -}, -#ifdef CONFIG_CPU_SUBTYPE_SH7760 -{ - .name = "hac-dai.1", - .id = 1, - .playback = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .capture = { - .rates = AC97_RATES, - .formats = AC97_FMTS, - .channels_min = 2, - .channels_max = 2, - }, - .ops = &hac_dai_ops, - -}, -#endif -}; - -static const struct snd_soc_component_driver sh4_hac_component = { - .name = "sh4-hac", - .legacy_dai_naming = 1, -}; - -static int hac_soc_platform_probe(struct platform_device *pdev) -{ - int ret; - - ret = snd_soc_set_ac97_ops(&hac_ac97_ops); - if (ret != 0) - return ret; - - return devm_snd_soc_register_component(&pdev->dev, &sh4_hac_component, - sh4_hac_dai, ARRAY_SIZE(sh4_hac_dai)); -} - -static int hac_soc_platform_remove(struct platform_device *pdev) -{ - snd_soc_set_ac97_ops(NULL); - return 0; -} - -static struct platform_driver hac_pcm_driver = { - .driver = { - .name = "hac-pcm-audio", - }, - - .probe = hac_soc_platform_probe, - .remove = hac_soc_platform_remove, -}; - -module_platform_driver(hac_pcm_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("SuperH onchip HAC (AC97) audio driver"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/sh/migor.c b/sound/soc/sh/migor.c deleted file mode 100644 index 7082c12d3bf238..00000000000000 --- a/sound/soc/sh/migor.c +++ /dev/null @@ -1,205 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// ALSA SoC driver for Migo-R -// -// Copyright (C) 2009-2010 Guennadi Liakhovetski - -#include -#include -#include -#include - -#include - -#include - -#include -#include -#include - -#include "../codecs/wm8978.h" -#include "siu.h" - -/* Default 8000Hz sampling frequency */ -static unsigned long codec_freq = 8000 * 512; - -static unsigned int use_count; - -/* External clock, sourced from the codec at the SIUMCKB pin */ -static unsigned long siumckb_recalc(struct clk *clk) -{ - return codec_freq; -} - -static struct sh_clk_ops siumckb_clk_ops = { - .recalc = siumckb_recalc, -}; - -static struct clk siumckb_clk = { - .ops = &siumckb_clk_ops, - .rate = 0, /* initialised at run-time */ -}; - -static struct clk_lookup *siumckb_lookup; - -static int migor_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - int ret; - unsigned int rate = params_rate(params); - - ret = snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 13000000, - SND_SOC_CLOCK_IN); - if (ret < 0) - return ret; - - ret = snd_soc_dai_set_clkdiv(codec_dai, WM8978_OPCLKRATE, rate * 512); - if (ret < 0) - return ret; - - codec_freq = rate * 512; - /* - * This propagates the parent frequency change to children and - * recalculates the frequency table - */ - clk_set_rate(&siumckb_clk, codec_freq); - dev_dbg(codec_dai->dev, "%s: configure %luHz\n", __func__, codec_freq); - - ret = snd_soc_dai_set_sysclk(asoc_rtd_to_cpu(rtd, 0), SIU_CLKB_EXT, - codec_freq / 2, SND_SOC_CLOCK_IN); - - if (!ret) - use_count++; - - return ret; -} - -static int migor_hw_free(struct snd_pcm_substream *substream) -{ - struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream); - struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0); - - if (use_count) { - use_count--; - - if (!use_count) - snd_soc_dai_set_sysclk(codec_dai, WM8978_PLL, 0, - SND_SOC_CLOCK_IN); - } else { - dev_dbg(codec_dai->dev, "Unbalanced hw_free!\n"); - } - - return 0; -} - -static const struct snd_soc_ops migor_dai_ops = { - .hw_params = migor_hw_params, - .hw_free = migor_hw_free, -}; - -static const struct snd_soc_dapm_widget migor_dapm_widgets[] = { - SND_SOC_DAPM_HP("Headphone", NULL), - SND_SOC_DAPM_MIC("Onboard Microphone", NULL), - SND_SOC_DAPM_MIC("External Microphone", NULL), -}; - -static const struct snd_soc_dapm_route audio_map[] = { - /* Headphone output connected to LHP/RHP, enable OUT4 for VMID */ - { "Headphone", NULL, "OUT4 VMID" }, - { "OUT4 VMID", NULL, "LHP" }, - { "OUT4 VMID", NULL, "RHP" }, - - /* On-board microphone */ - { "RMICN", NULL, "Mic Bias" }, - { "RMICP", NULL, "Mic Bias" }, - { "Mic Bias", NULL, "Onboard Microphone" }, - - /* External microphone */ - { "LMICN", NULL, "Mic Bias" }, - { "LMICP", NULL, "Mic Bias" }, - { "Mic Bias", NULL, "External Microphone" }, -}; - -/* migor digital audio interface glue - connects codec <--> CPU */ -SND_SOC_DAILINK_DEFS(wm8978, - DAILINK_COMP_ARRAY(COMP_CPU("siu-pcm-audio")), - DAILINK_COMP_ARRAY(COMP_CODEC("wm8978.0-001a", "wm8978-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("siu-pcm-audio"))); - -static struct snd_soc_dai_link migor_dai = { - .name = "wm8978", - .stream_name = "WM8978", - .dai_fmt = SND_SOC_DAIFMT_NB_IF | SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_CBS_CFS, - .ops = &migor_dai_ops, - SND_SOC_DAILINK_REG(wm8978), -}; - -/* migor audio machine driver */ -static struct snd_soc_card snd_soc_migor = { - .name = "Migo-R", - .owner = THIS_MODULE, - .dai_link = &migor_dai, - .num_links = 1, - - .dapm_widgets = migor_dapm_widgets, - .num_dapm_widgets = ARRAY_SIZE(migor_dapm_widgets), - .dapm_routes = audio_map, - .num_dapm_routes = ARRAY_SIZE(audio_map), -}; - -static struct platform_device *migor_snd_device; - -static int __init migor_init(void) -{ - int ret; - - ret = clk_register(&siumckb_clk); - if (ret < 0) - return ret; - - siumckb_lookup = clkdev_create(&siumckb_clk, "siumckb_clk", NULL); - if (!siumckb_lookup) { - ret = -ENOMEM; - goto eclkdevalloc; - } - - /* Port number used on this machine: port B */ - migor_snd_device = platform_device_alloc("soc-audio", 1); - if (!migor_snd_device) { - ret = -ENOMEM; - goto epdevalloc; - } - - platform_set_drvdata(migor_snd_device, &snd_soc_migor); - - ret = platform_device_add(migor_snd_device); - if (ret) - goto epdevadd; - - return 0; - -epdevadd: - platform_device_put(migor_snd_device); -epdevalloc: - clkdev_drop(siumckb_lookup); -eclkdevalloc: - clk_unregister(&siumckb_clk); - return ret; -} - -static void __exit migor_exit(void) -{ - clkdev_drop(siumckb_lookup); - clk_unregister(&siumckb_clk); - platform_device_unregister(migor_snd_device); -} - -module_init(migor_init); -module_exit(migor_exit); - -MODULE_AUTHOR("Guennadi Liakhovetski "); -MODULE_DESCRIPTION("ALSA SoC Migor"); -MODULE_LICENSE("GPL v2"); diff --git a/sound/soc/sh/sh7760-ac97.c b/sound/soc/sh/sh7760-ac97.c deleted file mode 100644 index d267243a159ba6..00000000000000 --- a/sound/soc/sh/sh7760-ac97.c +++ /dev/null @@ -1,72 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Generic AC97 sound support for SH7760 -// -// (c) 2007 Manuel Lauss - -#include -#include -#include -#include -#include -#include -#include - -#define IPSEL 0xFE400034 - -SND_SOC_DAILINK_DEFS(ac97, - DAILINK_COMP_ARRAY(COMP_CPU("hac-dai.0")), /* HAC0 */ - DAILINK_COMP_ARRAY(COMP_CODEC("ac97-codec", "ac97-hifi")), - DAILINK_COMP_ARRAY(COMP_PLATFORM("sh7760-pcm-audio"))); - -static struct snd_soc_dai_link sh7760_ac97_dai = { - .name = "AC97", - .stream_name = "AC97 HiFi", - SND_SOC_DAILINK_REG(ac97), -}; - -static struct snd_soc_card sh7760_ac97_soc_machine = { - .name = "SH7760 AC97", - .owner = THIS_MODULE, - .dai_link = &sh7760_ac97_dai, - .num_links = 1, -}; - -static struct platform_device *sh7760_ac97_snd_device; - -static int __init sh7760_ac97_init(void) -{ - int ret; - unsigned short ipsel; - - /* enable both AC97 controllers in pinmux reg */ - ipsel = __raw_readw(IPSEL); - __raw_writew(ipsel | (3 << 10), IPSEL); - - ret = -ENOMEM; - sh7760_ac97_snd_device = platform_device_alloc("soc-audio", -1); - if (!sh7760_ac97_snd_device) - goto out; - - platform_set_drvdata(sh7760_ac97_snd_device, - &sh7760_ac97_soc_machine); - ret = platform_device_add(sh7760_ac97_snd_device); - - if (ret) - platform_device_put(sh7760_ac97_snd_device); - -out: - return ret; -} - -static void __exit sh7760_ac97_exit(void) -{ - platform_device_unregister(sh7760_ac97_snd_device); -} - -module_init(sh7760_ac97_init); -module_exit(sh7760_ac97_exit); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("Generic SH7760 AC97 sound machine"); -MODULE_AUTHOR("Manuel Lauss "); diff --git a/sound/soc/sh/siu.h b/sound/soc/sh/siu.h deleted file mode 100644 index a675c36fc9d956..00000000000000 --- a/sound/soc/sh/siu.h +++ /dev/null @@ -1,180 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// siu.h - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral. -// -// Copyright (C) 2009-2010 Guennadi Liakhovetski -// Copyright (C) 2006 Carlos Munoz - -#ifndef SIU_H -#define SIU_H - -/* Common kernel and user-space firmware-building defines and types */ - -#define YRAM0_SIZE (0x0040 / 4) /* 16 */ -#define YRAM1_SIZE (0x0080 / 4) /* 32 */ -#define YRAM2_SIZE (0x0040 / 4) /* 16 */ -#define YRAM3_SIZE (0x0080 / 4) /* 32 */ -#define YRAM4_SIZE (0x0080 / 4) /* 32 */ -#define YRAM_DEF_SIZE (YRAM0_SIZE + YRAM1_SIZE + YRAM2_SIZE + \ - YRAM3_SIZE + YRAM4_SIZE) -#define YRAM_FIR_SIZE (0x0400 / 4) /* 256 */ -#define YRAM_IIR_SIZE (0x0200 / 4) /* 128 */ - -#define XRAM0_SIZE (0x0400 / 4) /* 256 */ -#define XRAM1_SIZE (0x0200 / 4) /* 128 */ -#define XRAM2_SIZE (0x0200 / 4) /* 128 */ - -/* PRAM program array size */ -#define PRAM0_SIZE (0x0100 / 4) /* 64 */ -#define PRAM1_SIZE ((0x2000 - 0x0100) / 4) /* 1984 */ - -#include - -struct siu_spb_param { - __u32 ab1a; /* input FIFO address */ - __u32 ab0a; /* output FIFO address */ - __u32 dir; /* 0=the ather except CPUOUTPUT, 1=CPUINPUT */ - __u32 event; /* SPB program starting conditions */ - __u32 stfifo; /* STFIFO register setting value */ - __u32 trdat; /* TRDAT register setting value */ -}; - -struct siu_firmware { - __u32 yram_fir_coeff[YRAM_FIR_SIZE]; - __u32 pram0[PRAM0_SIZE]; - __u32 pram1[PRAM1_SIZE]; - __u32 yram0[YRAM0_SIZE]; - __u32 yram1[YRAM1_SIZE]; - __u32 yram2[YRAM2_SIZE]; - __u32 yram3[YRAM3_SIZE]; - __u32 yram4[YRAM4_SIZE]; - __u32 spbpar_num; - struct siu_spb_param spbpar[32]; -}; - -#ifdef __KERNEL__ - -#include -#include -#include -#include - -#include -#include -#include - -#define SIU_PERIOD_BYTES_MAX 8192 /* DMA transfer/period size */ -#define SIU_PERIOD_BYTES_MIN 256 /* DMA transfer/period size */ -#define SIU_PERIODS_MAX 64 /* Max periods in buffer */ -#define SIU_PERIODS_MIN 4 /* Min periods in buffer */ -#define SIU_BUFFER_BYTES_MAX (SIU_PERIOD_BYTES_MAX * SIU_PERIODS_MAX) - -/* SIU ports: only one can be used at a time */ -enum { - SIU_PORT_A, - SIU_PORT_B, - SIU_PORT_NUM, -}; - -/* SIU clock configuration */ -enum { - SIU_CLKA_PLL, - SIU_CLKA_EXT, - SIU_CLKB_PLL, - SIU_CLKB_EXT -}; - -struct device; -struct siu_info { - struct device *dev; - int port_id; - u32 __iomem *pram; - u32 __iomem *xram; - u32 __iomem *yram; - u32 __iomem *reg; - struct siu_firmware fw; -}; - -struct siu_stream { - struct work_struct work; - struct snd_pcm_substream *substream; - snd_pcm_format_t format; - size_t buf_bytes; - size_t period_bytes; - int cur_period; /* Period currently in dma */ - u32 volume; - snd_pcm_sframes_t xfer_cnt; /* Number of frames */ - u8 rw_flg; /* transfer status */ - /* DMA status */ - struct dma_chan *chan; /* DMA channel */ - struct dma_async_tx_descriptor *tx_desc; - dma_cookie_t cookie; - struct sh_dmae_slave param; -}; - -struct siu_port { - unsigned long play_cap; /* Used to track full duplex */ - struct snd_pcm *pcm; - struct siu_stream playback; - struct siu_stream capture; - u32 stfifo; /* STFIFO value from firmware */ - u32 trdat; /* TRDAT value from firmware */ -}; - -extern struct siu_port *siu_ports[SIU_PORT_NUM]; - -static inline struct siu_port *siu_port_info(struct snd_pcm_substream *substream) -{ - struct platform_device *pdev = - to_platform_device(substream->pcm->card->dev); - return siu_ports[pdev->id]; -} - -/* Register access */ -static inline void siu_write32(u32 __iomem *addr, u32 val) -{ - __raw_writel(val, addr); -} - -static inline u32 siu_read32(u32 __iomem *addr) -{ - return __raw_readl(addr); -} - -/* SIU registers */ -#define SIU_IFCTL (0x000 / sizeof(u32)) -#define SIU_SRCTL (0x004 / sizeof(u32)) -#define SIU_SFORM (0x008 / sizeof(u32)) -#define SIU_CKCTL (0x00c / sizeof(u32)) -#define SIU_TRDAT (0x010 / sizeof(u32)) -#define SIU_STFIFO (0x014 / sizeof(u32)) -#define SIU_DPAK (0x01c / sizeof(u32)) -#define SIU_CKREV (0x020 / sizeof(u32)) -#define SIU_EVNTC (0x028 / sizeof(u32)) -#define SIU_SBCTL (0x040 / sizeof(u32)) -#define SIU_SBPSET (0x044 / sizeof(u32)) -#define SIU_SBFSTS (0x068 / sizeof(u32)) -#define SIU_SBDVCA (0x06c / sizeof(u32)) -#define SIU_SBDVCB (0x070 / sizeof(u32)) -#define SIU_SBACTIV (0x074 / sizeof(u32)) -#define SIU_DMAIA (0x090 / sizeof(u32)) -#define SIU_DMAIB (0x094 / sizeof(u32)) -#define SIU_DMAOA (0x098 / sizeof(u32)) -#define SIU_DMAOB (0x09c / sizeof(u32)) -#define SIU_DMAML (0x0a0 / sizeof(u32)) -#define SIU_SPSTS (0x0cc / sizeof(u32)) -#define SIU_SPCTL (0x0d0 / sizeof(u32)) -#define SIU_BRGASEL (0x100 / sizeof(u32)) -#define SIU_BRRA (0x104 / sizeof(u32)) -#define SIU_BRGBSEL (0x108 / sizeof(u32)) -#define SIU_BRRB (0x10c / sizeof(u32)) - -extern const struct snd_soc_component_driver siu_component; -extern struct siu_info *siu_i2s_data; - -int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card); -void siu_free_port(struct siu_port *port_info); - -#endif - -#endif /* SIU_H */ diff --git a/sound/soc/sh/siu_dai.c b/sound/soc/sh/siu_dai.c deleted file mode 100644 index f2a386fcd92e4d..00000000000000 --- a/sound/soc/sh/siu_dai.c +++ /dev/null @@ -1,799 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// siu_dai.c - ALSA SoC driver for Renesas SH7343, SH7722 SIU peripheral. -// -// Copyright (C) 2009-2010 Guennadi Liakhovetski -// Copyright (C) 2006 Carlos Munoz - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "siu.h" - -/* Board specifics */ -#if defined(CONFIG_CPU_SUBTYPE_SH7722) -# define SIU_MAX_VOLUME 0x1000 -#else -# define SIU_MAX_VOLUME 0x7fff -#endif - -#define PRAM_SIZE 0x2000 -#define XRAM_SIZE 0x800 -#define YRAM_SIZE 0x800 - -#define XRAM_OFFSET 0x4000 -#define YRAM_OFFSET 0x6000 -#define REG_OFFSET 0xc000 - -#define PLAYBACK_ENABLED 1 -#define CAPTURE_ENABLED 2 - -#define VOLUME_CAPTURE 0 -#define VOLUME_PLAYBACK 1 -#define DFLT_VOLUME_LEVEL 0x08000800 - -/* - * SPDIF is only available on port A and on some SIU implementations it is only - * available for input. Due to the lack of hardware to test it, SPDIF is left - * disabled in this driver version - */ -struct format_flag { - u32 i2s; - u32 pcm; - u32 spdif; - u32 mask; -}; - -struct port_flag { - struct format_flag playback; - struct format_flag capture; -}; - -struct siu_info *siu_i2s_data; - -static struct port_flag siu_flags[SIU_PORT_NUM] = { - [SIU_PORT_A] = { - .playback = { - .i2s = 0x50000000, - .pcm = 0x40000000, - .spdif = 0x80000000, /* not on all SIU versions */ - .mask = 0xd0000000, - }, - .capture = { - .i2s = 0x05000000, - .pcm = 0x04000000, - .spdif = 0x08000000, - .mask = 0x0d000000, - }, - }, - [SIU_PORT_B] = { - .playback = { - .i2s = 0x00500000, - .pcm = 0x00400000, - .spdif = 0, /* impossible - turn off */ - .mask = 0x00500000, - }, - .capture = { - .i2s = 0x00050000, - .pcm = 0x00040000, - .spdif = 0, /* impossible - turn off */ - .mask = 0x00050000, - }, - }, -}; - -static void siu_dai_start(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - - dev_dbg(port_info->pcm->card->dev, "%s\n", __func__); - - /* Issue software reset to siu */ - siu_write32(base + SIU_SRCTL, 0); - - /* Wait for the reset to take effect */ - udelay(1); - - port_info->stfifo = 0; - port_info->trdat = 0; - - /* portA, portB, SIU operate */ - siu_write32(base + SIU_SRCTL, 0x301); - - /* portA=256fs, portB=256fs */ - siu_write32(base + SIU_CKCTL, 0x40400000); - - /* portA's BRG does not divide SIUCKA */ - siu_write32(base + SIU_BRGASEL, 0); - siu_write32(base + SIU_BRRA, 0); - - /* portB's BRG divides SIUCKB by half */ - siu_write32(base + SIU_BRGBSEL, 1); - siu_write32(base + SIU_BRRB, 0); - - siu_write32(base + SIU_IFCTL, 0x44440000); - - /* portA: 32 bit/fs, master; portB: 32 bit/fs, master */ - siu_write32(base + SIU_SFORM, 0x0c0c0000); - - /* - * Volume levels: looks like the DSP firmware implements volume controls - * differently from what's described in the datasheet - */ - siu_write32(base + SIU_SBDVCA, port_info->playback.volume); - siu_write32(base + SIU_SBDVCB, port_info->capture.volume); -} - -static void siu_dai_stop(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - - /* SIU software reset */ - siu_write32(base + SIU_SRCTL, 0); -} - -static void siu_dai_spbAselect(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - struct siu_firmware *fw = &info->fw; - u32 *ydef = fw->yram0; - u32 idx; - - /* path A use */ - if (!info->port_id) - idx = 1; /* portA */ - else - idx = 2; /* portB */ - - ydef[0] = (fw->spbpar[idx].ab1a << 16) | - (fw->spbpar[idx].ab0a << 8) | - (fw->spbpar[idx].dir << 7) | 3; - ydef[1] = fw->yram0[1]; /* 0x03000300 */ - ydef[2] = (16 / 2) << 24; - ydef[3] = fw->yram0[3]; /* 0 */ - ydef[4] = fw->yram0[4]; /* 0 */ - ydef[7] = fw->spbpar[idx].event; - port_info->stfifo |= fw->spbpar[idx].stfifo; - port_info->trdat |= fw->spbpar[idx].trdat; -} - -static void siu_dai_spbBselect(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - struct siu_firmware *fw = &info->fw; - u32 *ydef = fw->yram0; - u32 idx; - - /* path B use */ - if (!info->port_id) - idx = 7; /* portA */ - else - idx = 8; /* portB */ - - ydef[5] = (fw->spbpar[idx].ab1a << 16) | - (fw->spbpar[idx].ab0a << 8) | 1; - ydef[6] = fw->spbpar[idx].event; - port_info->stfifo |= fw->spbpar[idx].stfifo; - port_info->trdat |= fw->spbpar[idx].trdat; -} - -static void siu_dai_open(struct siu_stream *siu_stream) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - u32 srctl, ifctl; - - srctl = siu_read32(base + SIU_SRCTL); - ifctl = siu_read32(base + SIU_IFCTL); - - switch (info->port_id) { - case SIU_PORT_A: - /* portA operates */ - srctl |= 0x200; - ifctl &= ~0xc2; - break; - case SIU_PORT_B: - /* portB operates */ - srctl |= 0x100; - ifctl &= ~0x31; - break; - } - - siu_write32(base + SIU_SRCTL, srctl); - /* Unmute and configure portA */ - siu_write32(base + SIU_IFCTL, ifctl); -} - -/* - * At the moment only fixed Left-upper, Left-lower, Right-upper, Right-lower - * packing is supported - */ -static void siu_dai_pcmdatapack(struct siu_stream *siu_stream) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - u32 dpak; - - dpak = siu_read32(base + SIU_DPAK); - - switch (info->port_id) { - case SIU_PORT_A: - dpak &= ~0xc0000000; - break; - case SIU_PORT_B: - dpak &= ~0x00c00000; - break; - } - - siu_write32(base + SIU_DPAK, dpak); -} - -static int siu_dai_spbstart(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_firmware *fw = &info->fw; - u32 *ydef = fw->yram0; - int cnt; - u32 __iomem *add; - u32 *ptr; - - /* Load SPB Program in PRAM */ - ptr = fw->pram0; - add = info->pram; - for (cnt = 0; cnt < PRAM0_SIZE; cnt++, add++, ptr++) - siu_write32(add, *ptr); - - ptr = fw->pram1; - add = info->pram + (0x0100 / sizeof(u32)); - for (cnt = 0; cnt < PRAM1_SIZE; cnt++, add++, ptr++) - siu_write32(add, *ptr); - - /* XRAM initialization */ - add = info->xram; - for (cnt = 0; cnt < XRAM0_SIZE + XRAM1_SIZE + XRAM2_SIZE; cnt++, add++) - siu_write32(add, 0); - - /* YRAM variable area initialization */ - add = info->yram; - for (cnt = 0; cnt < YRAM_DEF_SIZE; cnt++, add++) - siu_write32(add, ydef[cnt]); - - /* YRAM FIR coefficient area initialization */ - add = info->yram + (0x0200 / sizeof(u32)); - for (cnt = 0; cnt < YRAM_FIR_SIZE; cnt++, add++) - siu_write32(add, fw->yram_fir_coeff[cnt]); - - /* YRAM IIR coefficient area initialization */ - add = info->yram + (0x0600 / sizeof(u32)); - for (cnt = 0; cnt < YRAM_IIR_SIZE; cnt++, add++) - siu_write32(add, 0); - - siu_write32(base + SIU_TRDAT, port_info->trdat); - port_info->trdat = 0x0; - - - /* SPB start condition: software */ - siu_write32(base + SIU_SBACTIV, 0); - /* Start SPB */ - siu_write32(base + SIU_SBCTL, 0xc0000000); - /* Wait for program to halt */ - cnt = 0x10000; - while (--cnt && siu_read32(base + SIU_SBCTL) != 0x80000000) - cpu_relax(); - - if (!cnt) - return -EBUSY; - - /* SPB program start address setting */ - siu_write32(base + SIU_SBPSET, 0x00400000); - /* SPB hardware start(FIFOCTL source) */ - siu_write32(base + SIU_SBACTIV, 0xc0000000); - - return 0; -} - -static void siu_dai_spbstop(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - - siu_write32(base + SIU_SBACTIV, 0); - /* SPB stop */ - siu_write32(base + SIU_SBCTL, 0); - - port_info->stfifo = 0; -} - -/* API functions */ - -/* Playback and capture hardware properties are identical */ -static const struct snd_pcm_hardware siu_dai_pcm_hw = { - .info = SNDRV_PCM_INFO_INTERLEAVED, - .formats = SNDRV_PCM_FMTBIT_S16, - .rates = SNDRV_PCM_RATE_8000_48000, - .rate_min = 8000, - .rate_max = 48000, - .channels_min = 2, - .channels_max = 2, - .buffer_bytes_max = SIU_BUFFER_BYTES_MAX, - .period_bytes_min = SIU_PERIOD_BYTES_MIN, - .period_bytes_max = SIU_PERIOD_BYTES_MAX, - .periods_min = SIU_PERIODS_MIN, - .periods_max = SIU_PERIODS_MAX, -}; - -static int siu_dai_info_volume(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_info *uinfo) -{ - struct siu_port *port_info = snd_kcontrol_chip(kctrl); - - dev_dbg(port_info->pcm->card->dev, "%s\n", __func__); - - uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; - uinfo->count = 2; - uinfo->value.integer.min = 0; - uinfo->value.integer.max = SIU_MAX_VOLUME; - - return 0; -} - -static int siu_dai_get_volume(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_value *ucontrol) -{ - struct siu_port *port_info = snd_kcontrol_chip(kctrl); - struct device *dev = port_info->pcm->card->dev; - u32 vol; - - dev_dbg(dev, "%s\n", __func__); - - switch (kctrl->private_value) { - case VOLUME_PLAYBACK: - /* Playback is always on port 0 */ - vol = port_info->playback.volume; - ucontrol->value.integer.value[0] = vol & 0xffff; - ucontrol->value.integer.value[1] = vol >> 16 & 0xffff; - break; - case VOLUME_CAPTURE: - /* Capture is always on port 1 */ - vol = port_info->capture.volume; - ucontrol->value.integer.value[0] = vol & 0xffff; - ucontrol->value.integer.value[1] = vol >> 16 & 0xffff; - break; - default: - dev_err(dev, "%s() invalid private_value=%ld\n", - __func__, kctrl->private_value); - return -EINVAL; - } - - return 0; -} - -static int siu_dai_put_volume(struct snd_kcontrol *kctrl, - struct snd_ctl_elem_value *ucontrol) -{ - struct siu_port *port_info = snd_kcontrol_chip(kctrl); - struct device *dev = port_info->pcm->card->dev; - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - u32 new_vol; - u32 cur_vol; - - dev_dbg(dev, "%s\n", __func__); - - if (ucontrol->value.integer.value[0] < 0 || - ucontrol->value.integer.value[0] > SIU_MAX_VOLUME || - ucontrol->value.integer.value[1] < 0 || - ucontrol->value.integer.value[1] > SIU_MAX_VOLUME) - return -EINVAL; - - new_vol = ucontrol->value.integer.value[0] | - ucontrol->value.integer.value[1] << 16; - - /* See comment above - DSP firmware implementation */ - switch (kctrl->private_value) { - case VOLUME_PLAYBACK: - /* Playback is always on port 0 */ - cur_vol = port_info->playback.volume; - siu_write32(base + SIU_SBDVCA, new_vol); - port_info->playback.volume = new_vol; - break; - case VOLUME_CAPTURE: - /* Capture is always on port 1 */ - cur_vol = port_info->capture.volume; - siu_write32(base + SIU_SBDVCB, new_vol); - port_info->capture.volume = new_vol; - break; - default: - dev_err(dev, "%s() invalid private_value=%ld\n", - __func__, kctrl->private_value); - return -EINVAL; - } - - if (cur_vol != new_vol) - return 1; - - return 0; -} - -static const struct snd_kcontrol_new playback_controls = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Playback Volume", - .index = 0, - .info = siu_dai_info_volume, - .get = siu_dai_get_volume, - .put = siu_dai_put_volume, - .private_value = VOLUME_PLAYBACK, -}; - -static const struct snd_kcontrol_new capture_controls = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "PCM Capture Volume", - .index = 0, - .info = siu_dai_info_volume, - .get = siu_dai_get_volume, - .put = siu_dai_put_volume, - .private_value = VOLUME_CAPTURE, -}; - -int siu_init_port(int port, struct siu_port **port_info, struct snd_card *card) -{ - struct device *dev = card->dev; - struct snd_kcontrol *kctrl; - int ret; - - *port_info = kzalloc(sizeof(**port_info), GFP_KERNEL); - if (!*port_info) - return -ENOMEM; - - dev_dbg(dev, "%s: port #%d@%p\n", __func__, port, *port_info); - - (*port_info)->playback.volume = DFLT_VOLUME_LEVEL; - (*port_info)->capture.volume = DFLT_VOLUME_LEVEL; - - /* - * Add mixer support. The SPB is used to change the volume. Both - * ports use the same SPB. Therefore, we only register one - * control instance since it will be used by both channels. - * In error case we continue without controls. - */ - kctrl = snd_ctl_new1(&playback_controls, *port_info); - ret = snd_ctl_add(card, kctrl); - if (ret < 0) - dev_err(dev, - "failed to add playback controls %p port=%d err=%d\n", - kctrl, port, ret); - - kctrl = snd_ctl_new1(&capture_controls, *port_info); - ret = snd_ctl_add(card, kctrl); - if (ret < 0) - dev_err(dev, - "failed to add capture controls %p port=%d err=%d\n", - kctrl, port, ret); - - return 0; -} - -void siu_free_port(struct siu_port *port_info) -{ - kfree(port_info); -} - -static int siu_dai_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct siu_info *info = snd_soc_dai_get_drvdata(dai); - struct snd_pcm_runtime *rt = substream->runtime; - struct siu_port *port_info = siu_port_info(substream); - int ret; - - dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__, - info->port_id, port_info); - - snd_soc_set_runtime_hwparams(substream, &siu_dai_pcm_hw); - - ret = snd_pcm_hw_constraint_integer(rt, SNDRV_PCM_HW_PARAM_PERIODS); - if (unlikely(ret < 0)) - return ret; - - siu_dai_start(port_info); - - return 0; -} - -static void siu_dai_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct siu_info *info = snd_soc_dai_get_drvdata(dai); - struct siu_port *port_info = siu_port_info(substream); - - dev_dbg(substream->pcm->card->dev, "%s: port=%d@%p\n", __func__, - info->port_id, port_info); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) - port_info->play_cap &= ~PLAYBACK_ENABLED; - else - port_info->play_cap &= ~CAPTURE_ENABLED; - - /* Stop the siu if the other stream is not using it */ - if (!port_info->play_cap) { - /* during stmread or stmwrite ? */ - if (WARN_ON(port_info->playback.rw_flg || port_info->capture.rw_flg)) - return; - siu_dai_spbstop(port_info); - siu_dai_stop(port_info); - } -} - -/* PCM part of siu_dai_playback_prepare() / siu_dai_capture_prepare() */ -static int siu_dai_prepare(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct siu_info *info = snd_soc_dai_get_drvdata(dai); - struct snd_pcm_runtime *rt = substream->runtime; - struct siu_port *port_info = siu_port_info(substream); - struct siu_stream *siu_stream; - int self, ret; - - dev_dbg(substream->pcm->card->dev, - "%s: port %d, active streams %lx, %d channels\n", - __func__, info->port_id, port_info->play_cap, rt->channels); - - if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { - self = PLAYBACK_ENABLED; - siu_stream = &port_info->playback; - } else { - self = CAPTURE_ENABLED; - siu_stream = &port_info->capture; - } - - /* Set up the siu if not already done */ - if (!port_info->play_cap) { - siu_stream->rw_flg = 0; /* stream-data transfer flag */ - - siu_dai_spbAselect(port_info); - siu_dai_spbBselect(port_info); - - siu_dai_open(siu_stream); - - siu_dai_pcmdatapack(siu_stream); - - ret = siu_dai_spbstart(port_info); - if (ret < 0) - goto fail; - } else { - ret = 0; - } - - port_info->play_cap |= self; - -fail: - return ret; -} - -/* - * SIU can set bus format to I2S / PCM / SPDIF independently for playback and - * capture, however, the current API sets the bus format globally for a DAI. - */ -static int siu_dai_set_fmt(struct snd_soc_dai *dai, - unsigned int fmt) -{ - struct siu_info *info = snd_soc_dai_get_drvdata(dai); - u32 __iomem *base = info->reg; - u32 ifctl; - - dev_dbg(dai->dev, "%s: fmt 0x%x on port %d\n", - __func__, fmt, info->port_id); - - if (info->port_id < 0) - return -ENODEV; - - /* Here select between I2S / PCM / SPDIF */ - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - ifctl = siu_flags[info->port_id].playback.i2s | - siu_flags[info->port_id].capture.i2s; - break; - case SND_SOC_DAIFMT_LEFT_J: - ifctl = siu_flags[info->port_id].playback.pcm | - siu_flags[info->port_id].capture.pcm; - break; - /* SPDIF disabled - see comment at the top */ - default: - return -EINVAL; - } - - ifctl |= ~(siu_flags[info->port_id].playback.mask | - siu_flags[info->port_id].capture.mask) & - siu_read32(base + SIU_IFCTL); - siu_write32(base + SIU_IFCTL, ifctl); - - return 0; -} - -static int siu_dai_set_sysclk(struct snd_soc_dai *dai, int clk_id, - unsigned int freq, int dir) -{ - struct clk *siu_clk, *parent_clk; - char *siu_name, *parent_name; - int ret; - - if (dir != SND_SOC_CLOCK_IN) - return -EINVAL; - - dev_dbg(dai->dev, "%s: using clock %d\n", __func__, clk_id); - - switch (clk_id) { - case SIU_CLKA_PLL: - siu_name = "siua_clk"; - parent_name = "pll_clk"; - break; - case SIU_CLKA_EXT: - siu_name = "siua_clk"; - parent_name = "siumcka_clk"; - break; - case SIU_CLKB_PLL: - siu_name = "siub_clk"; - parent_name = "pll_clk"; - break; - case SIU_CLKB_EXT: - siu_name = "siub_clk"; - parent_name = "siumckb_clk"; - break; - default: - return -EINVAL; - } - - siu_clk = clk_get(dai->dev, siu_name); - if (IS_ERR(siu_clk)) { - dev_err(dai->dev, "%s: cannot get a SIU clock: %ld\n", __func__, - PTR_ERR(siu_clk)); - return PTR_ERR(siu_clk); - } - - parent_clk = clk_get(dai->dev, parent_name); - if (IS_ERR(parent_clk)) { - ret = PTR_ERR(parent_clk); - dev_err(dai->dev, "cannot get a SIU clock parent: %d\n", ret); - goto epclkget; - } - - ret = clk_set_parent(siu_clk, parent_clk); - if (ret < 0) { - dev_err(dai->dev, "cannot reparent the SIU clock: %d\n", ret); - goto eclksetp; - } - - ret = clk_set_rate(siu_clk, freq); - if (ret < 0) - dev_err(dai->dev, "cannot set SIU clock rate: %d\n", ret); - - /* TODO: when clkdev gets reference counting we'll move these to siu_dai_shutdown() */ -eclksetp: - clk_put(parent_clk); -epclkget: - clk_put(siu_clk); - - return ret; -} - -static const struct snd_soc_dai_ops siu_dai_ops = { - .startup = siu_dai_startup, - .shutdown = siu_dai_shutdown, - .prepare = siu_dai_prepare, - .set_sysclk = siu_dai_set_sysclk, - .set_fmt = siu_dai_set_fmt, -}; - -static struct snd_soc_dai_driver siu_i2s_dai = { - .name = "siu-i2s-dai", - .playback = { - .channels_min = 2, - .channels_max = 2, - .formats = SNDRV_PCM_FMTBIT_S16, - .rates = SNDRV_PCM_RATE_8000_48000, - }, - .capture = { - .channels_min = 2, - .channels_max = 2, - .formats = SNDRV_PCM_FMTBIT_S16, - .rates = SNDRV_PCM_RATE_8000_48000, - }, - .ops = &siu_dai_ops, -}; - -static int siu_probe(struct platform_device *pdev) -{ - const struct firmware *fw_entry; - struct resource *res, *region; - struct siu_info *info; - int ret; - - info = devm_kmalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); - if (!info) - return -ENOMEM; - siu_i2s_data = info; - info->dev = &pdev->dev; - - ret = request_firmware(&fw_entry, "siu_spb.bin", &pdev->dev); - if (ret) - return ret; - - /* - * Loaded firmware is "const" - read only, but we have to modify it in - * snd_siu_sh7343_spbAselect() and snd_siu_sh7343_spbBselect() - */ - memcpy(&info->fw, fw_entry->data, fw_entry->size); - - release_firmware(fw_entry); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) - return -ENODEV; - - region = devm_request_mem_region(&pdev->dev, res->start, - resource_size(res), pdev->name); - if (!region) { - dev_err(&pdev->dev, "SIU region already claimed\n"); - return -EBUSY; - } - - info->pram = devm_ioremap(&pdev->dev, res->start, PRAM_SIZE); - if (!info->pram) - return -ENOMEM; - info->xram = devm_ioremap(&pdev->dev, res->start + XRAM_OFFSET, - XRAM_SIZE); - if (!info->xram) - return -ENOMEM; - info->yram = devm_ioremap(&pdev->dev, res->start + YRAM_OFFSET, - YRAM_SIZE); - if (!info->yram) - return -ENOMEM; - info->reg = devm_ioremap(&pdev->dev, res->start + REG_OFFSET, - resource_size(res) - REG_OFFSET); - if (!info->reg) - return -ENOMEM; - - dev_set_drvdata(&pdev->dev, info); - - /* register using ARRAY version so we can keep dai name */ - ret = devm_snd_soc_register_component(&pdev->dev, &siu_component, - &siu_i2s_dai, 1); - if (ret < 0) - return ret; - - pm_runtime_enable(&pdev->dev); - - return 0; -} - -static int siu_remove(struct platform_device *pdev) -{ - pm_runtime_disable(&pdev->dev); - return 0; -} - -static struct platform_driver siu_driver = { - .driver = { - .name = "siu-pcm-audio", - }, - .probe = siu_probe, - .remove = siu_remove, -}; - -module_platform_driver(siu_driver); - -MODULE_AUTHOR("Carlos Munoz "); -MODULE_DESCRIPTION("ALSA SoC SH7722 SIU driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/sh/siu_pcm.c b/sound/soc/sh/siu_pcm.c deleted file mode 100644 index f15ff36e793455..00000000000000 --- a/sound/soc/sh/siu_pcm.c +++ /dev/null @@ -1,553 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -// -// siu_pcm.c - ALSA driver for Renesas SH7343, SH7722 SIU peripheral. -// -// Copyright (C) 2009-2010 Guennadi Liakhovetski -// Copyright (C) 2006 Carlos Munoz - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include - -#include "siu.h" - -#define DRV_NAME "siu-i2s" -#define GET_MAX_PERIODS(buf_bytes, period_bytes) \ - ((buf_bytes) / (period_bytes)) -#define PERIOD_OFFSET(buf_addr, period_num, period_bytes) \ - ((buf_addr) + ((period_num) * (period_bytes))) - -#define RWF_STM_RD 0x01 /* Read in progress */ -#define RWF_STM_WT 0x02 /* Write in progress */ - -struct siu_port *siu_ports[SIU_PORT_NUM]; - -/* transfersize is number of u32 dma transfers per period */ -static int siu_pcm_stmwrite_stop(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_stream *siu_stream = &port_info->playback; - u32 stfifo; - - if (!siu_stream->rw_flg) - return -EPERM; - - /* output FIFO disable */ - stfifo = siu_read32(base + SIU_STFIFO); - siu_write32(base + SIU_STFIFO, stfifo & ~0x0c180c18); - pr_debug("%s: STFIFO %x -> %x\n", __func__, - stfifo, stfifo & ~0x0c180c18); - - /* during stmwrite clear */ - siu_stream->rw_flg = 0; - - return 0; -} - -static int siu_pcm_stmwrite_start(struct siu_port *port_info) -{ - struct siu_stream *siu_stream = &port_info->playback; - - if (siu_stream->rw_flg) - return -EPERM; - - /* Current period in buffer */ - port_info->playback.cur_period = 0; - - /* during stmwrite flag set */ - siu_stream->rw_flg = RWF_STM_WT; - - /* DMA transfer start */ - queue_work(system_highpri_wq, &siu_stream->work); - - return 0; -} - -static void siu_dma_tx_complete(void *arg) -{ - struct siu_stream *siu_stream = arg; - - if (!siu_stream->rw_flg) - return; - - /* Update completed period count */ - if (++siu_stream->cur_period >= - GET_MAX_PERIODS(siu_stream->buf_bytes, - siu_stream->period_bytes)) - siu_stream->cur_period = 0; - - pr_debug("%s: done period #%d (%u/%u bytes), cookie %d\n", - __func__, siu_stream->cur_period, - siu_stream->cur_period * siu_stream->period_bytes, - siu_stream->buf_bytes, siu_stream->cookie); - - queue_work(system_highpri_wq, &siu_stream->work); - - /* Notify alsa: a period is done */ - snd_pcm_period_elapsed(siu_stream->substream); -} - -static int siu_pcm_wr_set(struct siu_port *port_info, - dma_addr_t buff, u32 size) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_stream *siu_stream = &port_info->playback; - struct snd_pcm_substream *substream = siu_stream->substream; - struct device *dev = substream->pcm->card->dev; - struct dma_async_tx_descriptor *desc; - dma_cookie_t cookie; - struct scatterlist sg; - u32 stfifo; - - sg_init_table(&sg, 1); - sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)), - size, offset_in_page(buff)); - sg_dma_len(&sg) = size; - sg_dma_address(&sg) = buff; - - desc = dmaengine_prep_slave_sg(siu_stream->chan, - &sg, 1, DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { - dev_err(dev, "Failed to allocate a dma descriptor\n"); - return -ENOMEM; - } - - desc->callback = siu_dma_tx_complete; - desc->callback_param = siu_stream; - cookie = dmaengine_submit(desc); - if (cookie < 0) { - dev_err(dev, "Failed to submit a dma transfer\n"); - return cookie; - } - - siu_stream->tx_desc = desc; - siu_stream->cookie = cookie; - - dma_async_issue_pending(siu_stream->chan); - - /* only output FIFO enable */ - stfifo = siu_read32(base + SIU_STFIFO); - siu_write32(base + SIU_STFIFO, stfifo | (port_info->stfifo & 0x0c180c18)); - dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, - stfifo, stfifo | (port_info->stfifo & 0x0c180c18)); - - return 0; -} - -static int siu_pcm_rd_set(struct siu_port *port_info, - dma_addr_t buff, size_t size) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_stream *siu_stream = &port_info->capture; - struct snd_pcm_substream *substream = siu_stream->substream; - struct device *dev = substream->pcm->card->dev; - struct dma_async_tx_descriptor *desc; - dma_cookie_t cookie; - struct scatterlist sg; - u32 stfifo; - - dev_dbg(dev, "%s: %u@%llx\n", __func__, size, (unsigned long long)buff); - - sg_init_table(&sg, 1); - sg_set_page(&sg, pfn_to_page(PFN_DOWN(buff)), - size, offset_in_page(buff)); - sg_dma_len(&sg) = size; - sg_dma_address(&sg) = buff; - - desc = dmaengine_prep_slave_sg(siu_stream->chan, - &sg, 1, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - if (!desc) { - dev_err(dev, "Failed to allocate dma descriptor\n"); - return -ENOMEM; - } - - desc->callback = siu_dma_tx_complete; - desc->callback_param = siu_stream; - cookie = dmaengine_submit(desc); - if (cookie < 0) { - dev_err(dev, "Failed to submit dma descriptor\n"); - return cookie; - } - - siu_stream->tx_desc = desc; - siu_stream->cookie = cookie; - - dma_async_issue_pending(siu_stream->chan); - - /* only input FIFO enable */ - stfifo = siu_read32(base + SIU_STFIFO); - siu_write32(base + SIU_STFIFO, siu_read32(base + SIU_STFIFO) | - (port_info->stfifo & 0x13071307)); - dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, - stfifo, stfifo | (port_info->stfifo & 0x13071307)); - - return 0; -} - -static void siu_io_work(struct work_struct *work) -{ - struct siu_stream *siu_stream = container_of(work, struct siu_stream, - work); - struct snd_pcm_substream *substream = siu_stream->substream; - struct device *dev = substream->pcm->card->dev; - struct snd_pcm_runtime *rt = substream->runtime; - struct siu_port *port_info = siu_port_info(substream); - - dev_dbg(dev, "%s: flags %x\n", __func__, siu_stream->rw_flg); - - if (!siu_stream->rw_flg) { - dev_dbg(dev, "%s: stream inactive\n", __func__); - return; - } - - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - dma_addr_t buff; - size_t count; - - buff = (dma_addr_t)PERIOD_OFFSET(rt->dma_addr, - siu_stream->cur_period, - siu_stream->period_bytes); - count = siu_stream->period_bytes; - - /* DMA transfer start */ - siu_pcm_rd_set(port_info, buff, count); - } else { - siu_pcm_wr_set(port_info, - (dma_addr_t)PERIOD_OFFSET(rt->dma_addr, - siu_stream->cur_period, - siu_stream->period_bytes), - siu_stream->period_bytes); - } -} - -/* Capture */ -static int siu_pcm_stmread_start(struct siu_port *port_info) -{ - struct siu_stream *siu_stream = &port_info->capture; - - if (siu_stream->xfer_cnt > 0x1000000) - return -EINVAL; - if (siu_stream->rw_flg) - return -EPERM; - - /* Current period in buffer */ - siu_stream->cur_period = 0; - - /* during stmread flag set */ - siu_stream->rw_flg = RWF_STM_RD; - - queue_work(system_highpri_wq, &siu_stream->work); - - return 0; -} - -static int siu_pcm_stmread_stop(struct siu_port *port_info) -{ - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_stream *siu_stream = &port_info->capture; - struct device *dev = siu_stream->substream->pcm->card->dev; - u32 stfifo; - - if (!siu_stream->rw_flg) - return -EPERM; - - /* input FIFO disable */ - stfifo = siu_read32(base + SIU_STFIFO); - siu_write32(base + SIU_STFIFO, stfifo & ~0x13071307); - dev_dbg(dev, "%s: STFIFO %x -> %x\n", __func__, - stfifo, stfifo & ~0x13071307); - - /* during stmread flag clear */ - siu_stream->rw_flg = 0; - - return 0; -} - -static bool filter(struct dma_chan *chan, void *secondary) -{ - struct sh_dmae_slave *param = secondary; - - pr_debug("%s: secondary ID %d\n", __func__, param->shdma_slave.slave_id); - - chan->private = ¶m->shdma_slave; - return true; -} - -static int siu_pcm_open(struct snd_soc_component *component, - struct snd_pcm_substream *ss) -{ - /* Playback / Capture */ - struct siu_platform *pdata = component->dev->platform_data; - struct siu_info *info = siu_i2s_data; - struct siu_port *port_info = siu_port_info(ss); - struct siu_stream *siu_stream; - u32 port = info->port_id; - struct device *dev = ss->pcm->card->dev; - dma_cap_mask_t mask; - struct sh_dmae_slave *param; - - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - dev_dbg(dev, "%s, port=%d@%p\n", __func__, port, port_info); - - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) { - siu_stream = &port_info->playback; - param = &siu_stream->param; - param->shdma_slave.slave_id = port ? pdata->dma_slave_tx_b : - pdata->dma_slave_tx_a; - } else { - siu_stream = &port_info->capture; - param = &siu_stream->param; - param->shdma_slave.slave_id = port ? pdata->dma_slave_rx_b : - pdata->dma_slave_rx_a; - } - - /* Get DMA channel */ - siu_stream->chan = dma_request_channel(mask, filter, param); - if (!siu_stream->chan) { - dev_err(dev, "DMA channel allocation failed!\n"); - return -EBUSY; - } - - siu_stream->substream = ss; - - return 0; -} - -static int siu_pcm_close(struct snd_soc_component *component, - struct snd_pcm_substream *ss) -{ - struct siu_info *info = siu_i2s_data; - struct device *dev = ss->pcm->card->dev; - struct siu_port *port_info = siu_port_info(ss); - struct siu_stream *siu_stream; - - dev_dbg(dev, "%s: port=%d\n", __func__, info->port_id); - - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - siu_stream = &port_info->playback; - else - siu_stream = &port_info->capture; - - dma_release_channel(siu_stream->chan); - siu_stream->chan = NULL; - - siu_stream->substream = NULL; - - return 0; -} - -static int siu_pcm_prepare(struct snd_soc_component *component, - struct snd_pcm_substream *ss) -{ - struct siu_info *info = siu_i2s_data; - struct siu_port *port_info = siu_port_info(ss); - struct device *dev = ss->pcm->card->dev; - struct snd_pcm_runtime *rt; - struct siu_stream *siu_stream; - snd_pcm_sframes_t xfer_cnt; - - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - siu_stream = &port_info->playback; - else - siu_stream = &port_info->capture; - - rt = siu_stream->substream->runtime; - - siu_stream->buf_bytes = snd_pcm_lib_buffer_bytes(ss); - siu_stream->period_bytes = snd_pcm_lib_period_bytes(ss); - - dev_dbg(dev, "%s: port=%d, %d channels, period=%u bytes\n", __func__, - info->port_id, rt->channels, siu_stream->period_bytes); - - /* We only support buffers that are multiples of the period */ - if (siu_stream->buf_bytes % siu_stream->period_bytes) { - dev_err(dev, "%s() - buffer=%d not multiple of period=%d\n", - __func__, siu_stream->buf_bytes, - siu_stream->period_bytes); - return -EINVAL; - } - - xfer_cnt = bytes_to_frames(rt, siu_stream->period_bytes); - if (!xfer_cnt || xfer_cnt > 0x1000000) - return -EINVAL; - - siu_stream->format = rt->format; - siu_stream->xfer_cnt = xfer_cnt; - - dev_dbg(dev, "port=%d buf=%lx buf_bytes=%d period_bytes=%d " - "format=%d channels=%d xfer_cnt=%d\n", info->port_id, - (unsigned long)rt->dma_addr, siu_stream->buf_bytes, - siu_stream->period_bytes, - siu_stream->format, rt->channels, (int)xfer_cnt); - - return 0; -} - -static int siu_pcm_trigger(struct snd_soc_component *component, - struct snd_pcm_substream *ss, int cmd) -{ - struct siu_info *info = siu_i2s_data; - struct device *dev = ss->pcm->card->dev; - struct siu_port *port_info = siu_port_info(ss); - int ret; - - dev_dbg(dev, "%s: port=%d@%p, cmd=%d\n", __func__, - info->port_id, port_info, cmd); - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - ret = siu_pcm_stmwrite_start(port_info); - else - ret = siu_pcm_stmread_start(port_info); - - if (ret < 0) - dev_warn(dev, "%s: start failed on port=%d\n", - __func__, info->port_id); - - break; - case SNDRV_PCM_TRIGGER_STOP: - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - siu_pcm_stmwrite_stop(port_info); - else - siu_pcm_stmread_stop(port_info); - ret = 0; - - break; - default: - dev_err(dev, "%s() unsupported cmd=%d\n", __func__, cmd); - ret = -EINVAL; - } - - return ret; -} - -/* - * So far only resolution of one period is supported, subject to extending the - * dmangine API - */ -static snd_pcm_uframes_t -siu_pcm_pointer_dma(struct snd_soc_component *component, - struct snd_pcm_substream *ss) -{ - struct device *dev = ss->pcm->card->dev; - struct siu_info *info = siu_i2s_data; - u32 __iomem *base = info->reg; - struct siu_port *port_info = siu_port_info(ss); - struct snd_pcm_runtime *rt = ss->runtime; - size_t ptr; - struct siu_stream *siu_stream; - - if (ss->stream == SNDRV_PCM_STREAM_PLAYBACK) - siu_stream = &port_info->playback; - else - siu_stream = &port_info->capture; - - /* - * ptr is the offset into the buffer where the dma is currently at. We - * check if the dma buffer has just wrapped. - */ - ptr = PERIOD_OFFSET(rt->dma_addr, - siu_stream->cur_period, - siu_stream->period_bytes) - rt->dma_addr; - - dev_dbg(dev, - "%s: port=%d, events %x, FSTS %x, xferred %u/%u, cookie %d\n", - __func__, info->port_id, siu_read32(base + SIU_EVNTC), - siu_read32(base + SIU_SBFSTS), ptr, siu_stream->buf_bytes, - siu_stream->cookie); - - if (ptr >= siu_stream->buf_bytes) - ptr = 0; - - return bytes_to_frames(ss->runtime, ptr); -} - -static int siu_pcm_new(struct snd_soc_component *component, - struct snd_soc_pcm_runtime *rtd) -{ - /* card->dev == socdev->dev, see snd_soc_new_pcms() */ - struct snd_card *card = rtd->card->snd_card; - struct snd_pcm *pcm = rtd->pcm; - struct siu_info *info = siu_i2s_data; - struct platform_device *pdev = to_platform_device(card->dev); - int ret; - int i; - - /* pdev->id selects between SIUA and SIUB */ - if (pdev->id < 0 || pdev->id >= SIU_PORT_NUM) - return -EINVAL; - - info->port_id = pdev->id; - - /* - * While the siu has 2 ports, only one port can be on at a time (only 1 - * SPB). So far all the boards using the siu had only one of the ports - * wired to a codec. To simplify things, we only register one port with - * alsa. In case both ports are needed, it should be changed here - */ - for (i = pdev->id; i < pdev->id + 1; i++) { - struct siu_port **port_info = &siu_ports[i]; - - ret = siu_init_port(i, port_info, card); - if (ret < 0) - return ret; - - snd_pcm_set_managed_buffer_all(pcm, - SNDRV_DMA_TYPE_DEV, card->dev, - SIU_BUFFER_BYTES_MAX, SIU_BUFFER_BYTES_MAX); - - (*port_info)->pcm = pcm; - - /* IO works */ - INIT_WORK(&(*port_info)->playback.work, siu_io_work); - INIT_WORK(&(*port_info)->capture.work, siu_io_work); - } - - dev_info(card->dev, "SuperH SIU driver initialized.\n"); - return 0; -} - -static void siu_pcm_free(struct snd_soc_component *component, - struct snd_pcm *pcm) -{ - struct platform_device *pdev = to_platform_device(pcm->card->dev); - struct siu_port *port_info = siu_ports[pdev->id]; - - cancel_work_sync(&port_info->capture.work); - cancel_work_sync(&port_info->playback.work); - - siu_free_port(port_info); - - dev_dbg(pcm->card->dev, "%s\n", __func__); -} - -const struct snd_soc_component_driver siu_component = { - .name = DRV_NAME, - .open = siu_pcm_open, - .close = siu_pcm_close, - .prepare = siu_pcm_prepare, - .trigger = siu_pcm_trigger, - .pointer = siu_pcm_pointer_dma, - .pcm_construct = siu_pcm_new, - .pcm_destruct = siu_pcm_free, - .legacy_dai_naming = 1, -}; -EXPORT_SYMBOL_GPL(siu_component); diff --git a/sound/soc/sh/ssi.c b/sound/soc/sh/ssi.c deleted file mode 100644 index 96cf523c227343..00000000000000 --- a/sound/soc/sh/ssi.c +++ /dev/null @@ -1,403 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -// -// Serial Sound Interface (I2S) support for SH7760/SH7780 -// -// Copyright (c) 2007 Manuel Lauss -// -// dont forget to set IPSEL/OMSEL register bits (in your board code) to -// enable SSI output pins! - -/* - * LIMITATIONS: - * The SSI unit has only one physical data line, so full duplex is - * impossible. This can be remedied on the SH7760 by using the - * other SSI unit for recording; however the SH7780 has only 1 SSI - * unit, and its pins are shared with the AC97 unit, among others. - * - * FEATURES: - * The SSI features "compressed mode": in this mode it continuously - * streams PCM data over the I2S lines and uses LRCK as a handshake - * signal. Can be used to send compressed data (AC3/DTS) to a DSP. - * The number of bits sent over the wire in a frame can be adjusted - * and can be independent from the actual sample bit depth. This is - * useful to support TDM mode codecs like the AD1939 which have a - * fixed TDM slot size, regardless of sample resolution. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define SSICR 0x00 -#define SSISR 0x04 - -#define CR_DMAEN (1 << 28) -#define CR_CHNL_SHIFT 22 -#define CR_CHNL_MASK (3 << CR_CHNL_SHIFT) -#define CR_DWL_SHIFT 19 -#define CR_DWL_MASK (7 << CR_DWL_SHIFT) -#define CR_SWL_SHIFT 16 -#define CR_SWL_MASK (7 << CR_SWL_SHIFT) -#define CR_SCK_MASTER (1 << 15) /* bitclock master bit */ -#define CR_SWS_MASTER (1 << 14) /* wordselect master bit */ -#define CR_SCKP (1 << 13) /* I2Sclock polarity */ -#define CR_SWSP (1 << 12) /* LRCK polarity */ -#define CR_SPDP (1 << 11) -#define CR_SDTA (1 << 10) /* i2s alignment (msb/lsb) */ -#define CR_PDTA (1 << 9) /* fifo data alignment */ -#define CR_DEL (1 << 8) /* delay data by 1 i2sclk */ -#define CR_BREN (1 << 7) /* clock gating in burst mode */ -#define CR_CKDIV_SHIFT 4 -#define CR_CKDIV_MASK (7 << CR_CKDIV_SHIFT) /* bitclock divider */ -#define CR_MUTE (1 << 3) /* SSI mute */ -#define CR_CPEN (1 << 2) /* compressed mode */ -#define CR_TRMD (1 << 1) /* transmit/receive select */ -#define CR_EN (1 << 0) /* enable SSI */ - -#define SSIREG(reg) (*(unsigned long *)(ssi->mmio + (reg))) - -struct ssi_priv { - unsigned long mmio; - unsigned long sysclk; - int inuse; -} ssi_cpu_data[] = { -#if defined(CONFIG_CPU_SUBTYPE_SH7760) - { - .mmio = 0xFE680000, - }, - { - .mmio = 0xFE690000, - }, -#elif defined(CONFIG_CPU_SUBTYPE_SH7780) - { - .mmio = 0xFFE70000, - }, -#else -#error "Unsupported SuperH SoC" -#endif -}; - -/* - * track usage of the SSI; it is simplex-only so prevent attempts of - * concurrent playback + capture. FIXME: any locking required? - */ -static int ssi_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - if (ssi->inuse) { - pr_debug("ssi: already in use!\n"); - return -EBUSY; - } else - ssi->inuse = 1; - return 0; -} - -static void ssi_shutdown(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - - ssi->inuse = 0; -} - -static int ssi_trigger(struct snd_pcm_substream *substream, int cmd, - struct snd_soc_dai *dai) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - - switch (cmd) { - case SNDRV_PCM_TRIGGER_START: - SSIREG(SSICR) |= CR_DMAEN | CR_EN; - break; - case SNDRV_PCM_TRIGGER_STOP: - SSIREG(SSICR) &= ~(CR_DMAEN | CR_EN); - break; - default: - return -EINVAL; - } - - return 0; -} - -static int ssi_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr = SSIREG(SSICR); - unsigned int bits, channels, swl, recv, i; - - channels = params_channels(params); - bits = params->msbits; - recv = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) ? 0 : 1; - - pr_debug("ssi_hw_params() enter\nssicr was %08lx\n", ssicr); - pr_debug("bits: %u channels: %u\n", bits, channels); - - ssicr &= ~(CR_TRMD | CR_CHNL_MASK | CR_DWL_MASK | CR_PDTA | - CR_SWL_MASK); - - /* direction (send/receive) */ - if (!recv) - ssicr |= CR_TRMD; /* transmit */ - - /* channels */ - if ((channels < 2) || (channels > 8) || (channels & 1)) { - pr_debug("ssi: invalid number of channels\n"); - return -EINVAL; - } - ssicr |= ((channels >> 1) - 1) << CR_CHNL_SHIFT; - - /* DATA WORD LENGTH (DWL): databits in audio sample */ - i = 0; - switch (bits) { - case 32: ++i; - case 24: ++i; - case 22: ++i; - case 20: ++i; - case 18: ++i; - case 16: ++i; - ssicr |= i << CR_DWL_SHIFT; - case 8: break; - default: - pr_debug("ssi: invalid sample width\n"); - return -EINVAL; - } - - /* - * SYSTEM WORD LENGTH: size in bits of half a frame over the I2S - * wires. This is usually bits_per_sample x channels/2; i.e. in - * Stereo mode the SWL equals DWL. SWL can be bigger than the - * product of (channels_per_slot x samplebits), e.g. for codecs - * like the AD1939 which only accept 32bit wide TDM slots. For - * "standard" I2S operation we set SWL = chans / 2 * DWL here. - * Waiting for ASoC to get TDM support ;-) - */ - if ((bits > 16) && (bits <= 24)) { - bits = 24; /* these are padded by the SSI */ - /*ssicr |= CR_PDTA;*/ /* cpu/data endianness ? */ - } - i = 0; - swl = (bits * channels) / 2; - switch (swl) { - case 256: ++i; - case 128: ++i; - case 64: ++i; - case 48: ++i; - case 32: ++i; - case 16: ++i; - ssicr |= i << CR_SWL_SHIFT; - case 8: break; - default: - pr_debug("ssi: invalid system word length computed\n"); - return -EINVAL; - } - - SSIREG(SSICR) = ssicr; - - pr_debug("ssi_hw_params() leave\nssicr is now %08lx\n", ssicr); - return 0; -} - -static int ssi_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, - unsigned int freq, int dir) -{ - struct ssi_priv *ssi = &ssi_cpu_data[cpu_dai->id]; - - ssi->sysclk = freq; - - return 0; -} - -/* - * This divider is used to generate the SSI_SCK (I2S bitclock) from the - * clock at the HAC_BIT_CLK ("oversampling clock") pin. - */ -static int ssi_set_clkdiv(struct snd_soc_dai *dai, int did, int div) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr; - int i; - - i = 0; - ssicr = SSIREG(SSICR) & ~CR_CKDIV_MASK; - switch (div) { - case 16: ++i; - case 8: ++i; - case 4: ++i; - case 2: ++i; - SSIREG(SSICR) = ssicr | (i << CR_CKDIV_SHIFT); - case 1: break; - default: - pr_debug("ssi: invalid sck divider %d\n", div); - return -EINVAL; - } - - return 0; -} - -static int ssi_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) -{ - struct ssi_priv *ssi = &ssi_cpu_data[dai->id]; - unsigned long ssicr = SSIREG(SSICR); - - pr_debug("ssi_set_fmt()\nssicr was 0x%08lx\n", ssicr); - - ssicr &= ~(CR_DEL | CR_PDTA | CR_BREN | CR_SWSP | CR_SCKP | - CR_SWS_MASTER | CR_SCK_MASTER); - - switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { - case SND_SOC_DAIFMT_I2S: - break; - case SND_SOC_DAIFMT_RIGHT_J: - ssicr |= CR_DEL | CR_PDTA; - break; - case SND_SOC_DAIFMT_LEFT_J: - ssicr |= CR_DEL; - break; - default: - pr_debug("ssi: unsupported format\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) { - case SND_SOC_DAIFMT_CONT: - break; - case SND_SOC_DAIFMT_GATED: - ssicr |= CR_BREN; - break; - } - - switch (fmt & SND_SOC_DAIFMT_INV_MASK) { - case SND_SOC_DAIFMT_NB_NF: - ssicr |= CR_SCKP; /* sample data at low clkedge */ - break; - case SND_SOC_DAIFMT_NB_IF: - ssicr |= CR_SCKP | CR_SWSP; - break; - case SND_SOC_DAIFMT_IB_NF: - break; - case SND_SOC_DAIFMT_IB_IF: - ssicr |= CR_SWSP; /* word select starts low */ - break; - default: - pr_debug("ssi: invalid inversion\n"); - return -EINVAL; - } - - switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { - case SND_SOC_DAIFMT_BC_FC: - break; - case SND_SOC_DAIFMT_BP_FC: - ssicr |= CR_SCK_MASTER; - break; - case SND_SOC_DAIFMT_BC_FP: - ssicr |= CR_SWS_MASTER; - break; - case SND_SOC_DAIFMT_BP_FP: - ssicr |= CR_SWS_MASTER | CR_SCK_MASTER; - break; - default: - pr_debug("ssi: invalid master/secondary configuration\n"); - return -EINVAL; - } - - SSIREG(SSICR) = ssicr; - pr_debug("ssi_set_fmt() leave\nssicr is now 0x%08lx\n", ssicr); - - return 0; -} - -/* the SSI depends on an external clocksource (at HAC_BIT_CLK) even in - * Master mode, so really this is board specific; the SSI can do any - * rate with the right bitclk and divider settings. - */ -#define SSI_RATES \ - SNDRV_PCM_RATE_8000_192000 - -/* the SSI can do 8-32 bit samples, with 8 possible channels */ -#define SSI_FMTS \ - (SNDRV_PCM_FMTBIT_S8 | SNDRV_PCM_FMTBIT_U8 | \ - SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_U16_LE | \ - SNDRV_PCM_FMTBIT_S20_3LE | SNDRV_PCM_FMTBIT_U20_3LE | \ - SNDRV_PCM_FMTBIT_S24_3LE | SNDRV_PCM_FMTBIT_U24_3LE | \ - SNDRV_PCM_FMTBIT_S32_LE | SNDRV_PCM_FMTBIT_U32_LE) - -static const struct snd_soc_dai_ops ssi_dai_ops = { - .startup = ssi_startup, - .shutdown = ssi_shutdown, - .trigger = ssi_trigger, - .hw_params = ssi_hw_params, - .set_sysclk = ssi_set_sysclk, - .set_clkdiv = ssi_set_clkdiv, - .set_fmt = ssi_set_fmt, -}; - -static struct snd_soc_dai_driver sh4_ssi_dai[] = { -{ - .name = "ssi-dai.0", - .playback = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .capture = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .ops = &ssi_dai_ops, -}, -#ifdef CONFIG_CPU_SUBTYPE_SH7760 -{ - .name = "ssi-dai.1", - .playback = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .capture = { - .rates = SSI_RATES, - .formats = SSI_FMTS, - .channels_min = 2, - .channels_max = 8, - }, - .ops = &ssi_dai_ops, -}, -#endif -}; - -static const struct snd_soc_component_driver sh4_ssi_component = { - .name = "sh4-ssi", - .legacy_dai_naming = 1, -}; - -static int sh4_soc_dai_probe(struct platform_device *pdev) -{ - return devm_snd_soc_register_component(&pdev->dev, &sh4_ssi_component, - sh4_ssi_dai, - ARRAY_SIZE(sh4_ssi_dai)); -} - -static struct platform_driver sh4_ssi_driver = { - .driver = { - .name = "sh4-ssi-dai", - }, - - .probe = sh4_soc_dai_probe, -}; - -module_platform_driver(sh4_ssi_driver); - -MODULE_LICENSE("GPL v2"); -MODULE_DESCRIPTION("SuperH onchip SSI (I2S) audio driver"); -MODULE_AUTHOR("Manuel Lauss "); From patchwork Fri Jan 13 06:23:23 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642271 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 62FDFC61DB3 for ; Fri, 13 Jan 2023 06:29:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238082AbjAMG1I (ORCPT ); Fri, 13 Jan 2023 01:27:08 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33502 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236952AbjAMGYr (ORCPT ); Fri, 13 Jan 2023 01:24:47 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 05B766A0F5; Thu, 12 Jan 2023 22:24:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=mxBIoTcWoM961bskFu4vgLYA4iK6lfkfHo46ovOHhdY=; b=epactF3LWIS1c8xybu121AnX4l mxQDeqmEC9J8cgMc2SIYAO9NzF3h0YlU8xbCTYRLLK24zqc8kEMH0PpbDIl1CALQ06M6j2t+DvW/2 52IjFzvuXiBDn229AAQmQ76IVBLDEALsaXsG/rhqbYhzaI4Hb2k5FYwBW/QtpL+GpgBj1CYNBCjoU Wow0ecEypZirO8g6qBKEcpON8H7jgnTwizxUEhR74JGhqggyXfr0uC5oDRw7YO7Ldj7yKS+YzcUmZ aD+BC5AU+OusXU3+GAHmRsZapXMUIGr4gkeRILIjbZ4eJzhz4I3ZIHuh91N7YMYtmI2wXUBJeRcBz reMo6ZfA==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDTy-000lWK-J8; Fri, 13 Jan 2023 06:24:07 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 06/22] watchdog: remove the shwdt driver Date: Fri, 13 Jan 2023 07:23:23 +0100 Message-Id: <20230113062339.1909087-7-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- .../watchdog/watchdog-parameters.rst | 12 - drivers/watchdog/Kconfig | 20 - drivers/watchdog/Makefile | 3 - drivers/watchdog/shwdt.c | 344 ------------------ 4 files changed, 379 deletions(-) delete mode 100644 drivers/watchdog/shwdt.c diff --git a/Documentation/watchdog/watchdog-parameters.rst b/Documentation/watchdog/watchdog-parameters.rst index 29153eed668900..553ac2f8ae23f7 100644 --- a/Documentation/watchdog/watchdog-parameters.rst +++ b/Documentation/watchdog/watchdog-parameters.rst @@ -579,18 +579,6 @@ scx200_wdt: ------------------------------------------------- -shwdt: - clock_division_ratio: - Clock division ratio. Valid ranges are from 0x5 (1.31ms) - to 0x7 (5.25ms). (default=7) - heartbeat: - Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default=30 - nowayout: - Watchdog cannot be stopped once started - (default=kernel config parameter) - -------------------------------------------------- - smsc37b787_wdt: timeout: range is 1-255 units, default is 60 diff --git a/drivers/watchdog/Kconfig b/drivers/watchdog/Kconfig index 0bc40b763b0652..7db0a5e636cf65 100644 --- a/drivers/watchdog/Kconfig +++ b/drivers/watchdog/Kconfig @@ -2015,26 +2015,6 @@ config DIAG288_WATCHDOG To compile this driver as a module, choose M here. The module will be called diag288_wdt. -# SUPERH (sh + sh64) Architecture - -config SH_WDT - tristate "SuperH Watchdog" - depends on SUPERH && (CPU_SH3 || CPU_SH4 || COMPILE_TEST) - select WATCHDOG_CORE - help - This driver adds watchdog support for the integrated watchdog in the - SuperH processors. If you have one of these processors and wish - to have watchdog support enabled, say Y, otherwise say N. - - As a side note, saying Y here will automatically boost HZ to 1000 - so that the timer has a chance to clear the overflow counter. On - slower systems (such as the SH-2 and SH-3) this will likely yield - some performance issues. As such, the WDT should be avoided here - unless it is absolutely necessary. - - To compile this driver as a module, choose M here: the - module will be called shwdt. - # SPARC Architecture # SPARC64 Architecture diff --git a/drivers/watchdog/Makefile b/drivers/watchdog/Makefile index 9cbf6580f16c9f..a852ab4d7176ac 100644 --- a/drivers/watchdog/Makefile +++ b/drivers/watchdog/Makefile @@ -195,9 +195,6 @@ obj-$(CONFIG_WATCHDOG_RTAS) += wdrtas.o # S390 Architecture obj-$(CONFIG_DIAG288_WATCHDOG) += diag288_wdt.o -# SUPERH (sh + sh64) Architecture -obj-$(CONFIG_SH_WDT) += shwdt.o - # SPARC Architecture # SPARC64 Architecture diff --git a/drivers/watchdog/shwdt.c b/drivers/watchdog/shwdt.c deleted file mode 100644 index f55533e0e0454e..00000000000000 --- a/drivers/watchdog/shwdt.c +++ /dev/null @@ -1,344 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later -/* - * drivers/watchdog/shwdt.c - * - * Watchdog driver for integrated watchdog in the SuperH processors. - * - * Copyright (C) 2001 - 2012 Paul Mundt - * - * 14-Dec-2001 Matt Domsch - * Added nowayout module option to override CONFIG_WATCHDOG_NOWAYOUT - * - * 19-Apr-2002 Rob Radez - * Added expect close support, made emulated timeout runtime changeable - * general cleanups, add some ioctls - */ - -#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRV_NAME "sh-wdt" - -/* - * Default clock division ratio is 5.25 msecs. For an additional table of - * values, consult the asm-sh/watchdog.h. Overload this at module load - * time. - * - * In order for this to work reliably we need to have HZ set to 1000 or - * something quite higher than 100 (or we need a proper high-res timer - * implementation that will deal with this properly), otherwise the 10ms - * resolution of a jiffy is enough to trigger the overflow. For things like - * the SH-4 and SH-5, this isn't necessarily that big of a problem, though - * for the SH-2 and SH-3, this isn't recommended unless the WDT is absolutely - * necssary. - * - * As a result of this timing problem, the only modes that are particularly - * feasible are the 4096 and the 2048 divisors, which yield 5.25 and 2.62ms - * overflow periods respectively. - * - * Also, since we can't really expect userspace to be responsive enough - * before the overflow happens, we maintain two separate timers .. One in - * the kernel for clearing out WOVF every 2ms or so (again, this depends on - * HZ == 1000), and another for monitoring userspace writes to the WDT device. - * - * As such, we currently use a configurable heartbeat interval which defaults - * to 30s. In this case, the userspace daemon is only responsible for periodic - * writes to the device before the next heartbeat is scheduled. If the daemon - * misses its deadline, the kernel timer will allow the WDT to overflow. - */ -static int clock_division_ratio = WTCSR_CKS_4096; -#define next_ping_period(cks) (jiffies + msecs_to_jiffies(cks - 4)) - -#define WATCHDOG_HEARTBEAT 30 /* 30 sec default heartbeat */ -static int heartbeat = WATCHDOG_HEARTBEAT; /* in seconds */ -static bool nowayout = WATCHDOG_NOWAYOUT; -static unsigned long next_heartbeat; - -struct sh_wdt { - void __iomem *base; - struct device *dev; - struct clk *clk; - spinlock_t lock; - - struct timer_list timer; -}; - -static int sh_wdt_start(struct watchdog_device *wdt_dev) -{ - struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); - unsigned long flags; - u8 csr; - - pm_runtime_get_sync(wdt->dev); - clk_enable(wdt->clk); - - spin_lock_irqsave(&wdt->lock, flags); - - next_heartbeat = jiffies + (heartbeat * HZ); - mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); - - csr = sh_wdt_read_csr(); - csr |= WTCSR_WT | clock_division_ratio; - sh_wdt_write_csr(csr); - - sh_wdt_write_cnt(0); - - /* - * These processors have a bit of an inconsistent initialization - * process.. starting with SH-3, RSTS was moved to WTCSR, and the - * RSTCSR register was removed. - * - * On the SH-2 however, in addition with bits being in different - * locations, we must deal with RSTCSR outright.. - */ - csr = sh_wdt_read_csr(); - csr |= WTCSR_TME; - csr &= ~WTCSR_RSTS; - sh_wdt_write_csr(csr); - -#ifdef CONFIG_CPU_SH2 - csr = sh_wdt_read_rstcsr(); - csr &= ~RSTCSR_RSTS; - sh_wdt_write_rstcsr(csr); -#endif - spin_unlock_irqrestore(&wdt->lock, flags); - - return 0; -} - -static int sh_wdt_stop(struct watchdog_device *wdt_dev) -{ - struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); - unsigned long flags; - u8 csr; - - spin_lock_irqsave(&wdt->lock, flags); - - del_timer(&wdt->timer); - - csr = sh_wdt_read_csr(); - csr &= ~WTCSR_TME; - sh_wdt_write_csr(csr); - - spin_unlock_irqrestore(&wdt->lock, flags); - - clk_disable(wdt->clk); - pm_runtime_put_sync(wdt->dev); - - return 0; -} - -static int sh_wdt_keepalive(struct watchdog_device *wdt_dev) -{ - struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); - unsigned long flags; - - spin_lock_irqsave(&wdt->lock, flags); - next_heartbeat = jiffies + (heartbeat * HZ); - spin_unlock_irqrestore(&wdt->lock, flags); - - return 0; -} - -static int sh_wdt_set_heartbeat(struct watchdog_device *wdt_dev, unsigned t) -{ - struct sh_wdt *wdt = watchdog_get_drvdata(wdt_dev); - unsigned long flags; - - if (unlikely(t < 1 || t > 3600)) /* arbitrary upper limit */ - return -EINVAL; - - spin_lock_irqsave(&wdt->lock, flags); - heartbeat = t; - wdt_dev->timeout = t; - spin_unlock_irqrestore(&wdt->lock, flags); - - return 0; -} - -static void sh_wdt_ping(struct timer_list *t) -{ - struct sh_wdt *wdt = from_timer(wdt, t, timer); - unsigned long flags; - - spin_lock_irqsave(&wdt->lock, flags); - if (time_before(jiffies, next_heartbeat)) { - u8 csr; - - csr = sh_wdt_read_csr(); - csr &= ~WTCSR_IOVF; - sh_wdt_write_csr(csr); - - sh_wdt_write_cnt(0); - - mod_timer(&wdt->timer, next_ping_period(clock_division_ratio)); - } else - dev_warn(wdt->dev, "Heartbeat lost! Will not ping " - "the watchdog\n"); - spin_unlock_irqrestore(&wdt->lock, flags); -} - -static const struct watchdog_info sh_wdt_info = { - .options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | - WDIOF_MAGICCLOSE, - .firmware_version = 1, - .identity = "SH WDT", -}; - -static const struct watchdog_ops sh_wdt_ops = { - .owner = THIS_MODULE, - .start = sh_wdt_start, - .stop = sh_wdt_stop, - .ping = sh_wdt_keepalive, - .set_timeout = sh_wdt_set_heartbeat, -}; - -static struct watchdog_device sh_wdt_dev = { - .info = &sh_wdt_info, - .ops = &sh_wdt_ops, -}; - -static int sh_wdt_probe(struct platform_device *pdev) -{ - struct sh_wdt *wdt; - int rc; - - /* - * As this driver only covers the global watchdog case, reject - * any attempts to register per-CPU watchdogs. - */ - if (pdev->id != -1) - return -EINVAL; - - wdt = devm_kzalloc(&pdev->dev, sizeof(struct sh_wdt), GFP_KERNEL); - if (unlikely(!wdt)) - return -ENOMEM; - - wdt->dev = &pdev->dev; - - wdt->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(wdt->clk)) { - /* - * Clock framework support is optional, continue on - * anyways if we don't find a matching clock. - */ - wdt->clk = NULL; - } - - wdt->base = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(wdt->base)) - return PTR_ERR(wdt->base); - - watchdog_set_nowayout(&sh_wdt_dev, nowayout); - watchdog_set_drvdata(&sh_wdt_dev, wdt); - sh_wdt_dev.parent = &pdev->dev; - - spin_lock_init(&wdt->lock); - - rc = sh_wdt_set_heartbeat(&sh_wdt_dev, heartbeat); - if (unlikely(rc)) { - /* Default timeout if invalid */ - sh_wdt_set_heartbeat(&sh_wdt_dev, WATCHDOG_HEARTBEAT); - - dev_warn(&pdev->dev, - "heartbeat value must be 1<=x<=3600, using %d\n", - sh_wdt_dev.timeout); - } - - dev_info(&pdev->dev, "configured with heartbeat=%d sec (nowayout=%d)\n", - sh_wdt_dev.timeout, nowayout); - - rc = watchdog_register_device(&sh_wdt_dev); - if (unlikely(rc)) { - dev_err(&pdev->dev, "Can't register watchdog (err=%d)\n", rc); - return rc; - } - - timer_setup(&wdt->timer, sh_wdt_ping, 0); - wdt->timer.expires = next_ping_period(clock_division_ratio); - - dev_info(&pdev->dev, "initialized.\n"); - - pm_runtime_enable(&pdev->dev); - - return 0; -} - -static int sh_wdt_remove(struct platform_device *pdev) -{ - watchdog_unregister_device(&sh_wdt_dev); - - pm_runtime_disable(&pdev->dev); - - return 0; -} - -static void sh_wdt_shutdown(struct platform_device *pdev) -{ - sh_wdt_stop(&sh_wdt_dev); -} - -static struct platform_driver sh_wdt_driver = { - .driver = { - .name = DRV_NAME, - }, - - .probe = sh_wdt_probe, - .remove = sh_wdt_remove, - .shutdown = sh_wdt_shutdown, -}; - -static int __init sh_wdt_init(void) -{ - if (unlikely(clock_division_ratio < 0x5 || - clock_division_ratio > 0x7)) { - clock_division_ratio = WTCSR_CKS_4096; - - pr_info("divisor must be 0x5<=x<=0x7, using %d\n", - clock_division_ratio); - } - - return platform_driver_register(&sh_wdt_driver); -} - -static void __exit sh_wdt_exit(void) -{ - platform_driver_unregister(&sh_wdt_driver); -} -module_init(sh_wdt_init); -module_exit(sh_wdt_exit); - -MODULE_AUTHOR("Paul Mundt "); -MODULE_DESCRIPTION("SuperH watchdog driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:" DRV_NAME); - -module_param(clock_division_ratio, int, 0); -MODULE_PARM_DESC(clock_division_ratio, - "Clock division ratio. Valid ranges are from 0x5 (1.31ms) " - "to 0x7 (5.25ms). (default=" __MODULE_STRING(WTCSR_CKS_4096) ")"); - -module_param(heartbeat, int, 0); -MODULE_PARM_DESC(heartbeat, - "Watchdog heartbeat in seconds. (1 <= heartbeat <= 3600, default=" - __MODULE_STRING(WATCHDOG_HEARTBEAT) ")"); - -module_param(nowayout, bool, 0); -MODULE_PARM_DESC(nowayout, - "Watchdog cannot be stopped once started (default=" - __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); From patchwork Fri Jan 13 06:23:26 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642273 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 95826C54EBD for ; Fri, 13 Jan 2023 06:27:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S238274AbjAMG1M (ORCPT ); Fri, 13 Jan 2023 01:27:12 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33512 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239960AbjAMGZF (ORCPT ); Fri, 13 Jan 2023 01:25:05 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 58A72D5F; Thu, 12 Jan 2023 22:24:26 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=2hPC7zlGA9AoDVV3UDFLI3T20RnHyuVZW1qr++X92oI=; b=U0IxPDIbDusxYyls7GAP+XZ9hs WK31Rw57DTsJeVGBg+mDkhc5spH2HTT6S2bZUnUWnMFMzjuRTQxHiqWupbwLk1M9gy0H80/2TyLAr 4yZAcNURNOrPm5QlFyeBEx9lyjEDdoNyEPtXoGtYw9kpeDRvlQIm1jqEylL4Lcd6JGXKqeXaBK+NJ +uk9CHMdgG+2G6uVa800FbCPfygKQQtSqfcvxslcKVFQl/oOPnfpUDUTut6HA5FBLlzfI2NTovRY8 7+tTh7eQy6PkL+5LvQ1o6k2FC089tht54mg8KW+qjbhQzzqpgcZGx2HuDPkTk929Z5PbzaycfkZ5t Zk42lm1g==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDU8-000lc0-50; Fri, 13 Jan 2023 06:24:16 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 09/22] i2c: remove i2c-sh7760 Date: Fri, 13 Jan 2023 07:23:26 +0100 Message-Id: <20230113062339.1909087-10-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/i2c/busses/Kconfig | 9 - drivers/i2c/busses/Makefile | 1 - drivers/i2c/busses/i2c-sh7760.c | 565 -------------------------------- 3 files changed, 575 deletions(-) delete mode 100644 drivers/i2c/busses/i2c-sh7760.c diff --git a/drivers/i2c/busses/Kconfig b/drivers/i2c/busses/Kconfig index 22602c512a6e50..44267a023fd19a 100644 --- a/drivers/i2c/busses/Kconfig +++ b/drivers/i2c/busses/Kconfig @@ -1016,15 +1016,6 @@ config I2C_S3C2410 Say Y here to include support for I2C controller in the Samsung SoCs (S3C, S5Pv210, Exynos). -config I2C_SH7760 - tristate "Renesas SH7760 I2C Controller" - depends on CPU_SUBTYPE_SH7760 - help - This driver supports the 2 I2C interfaces on the Renesas SH7760. - - This driver can also be built as a module. If so, the module - will be called i2c-sh7760. - config I2C_SH_MOBILE tristate "SuperH Mobile I2C Controller" depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/i2c/busses/Makefile b/drivers/i2c/busses/Makefile index e73cdb1d2b5a85..6be213e5e4dd16 100644 --- a/drivers/i2c/busses/Makefile +++ b/drivers/i2c/busses/Makefile @@ -104,7 +104,6 @@ obj-$(CONFIG_I2C_RIIC) += i2c-riic.o obj-$(CONFIG_I2C_RK3X) += i2c-rk3x.o obj-$(CONFIG_I2C_RZV2M) += i2c-rzv2m.o obj-$(CONFIG_I2C_S3C2410) += i2c-s3c2410.o -obj-$(CONFIG_I2C_SH7760) += i2c-sh7760.o obj-$(CONFIG_I2C_SH_MOBILE) += i2c-sh_mobile.o obj-$(CONFIG_I2C_SIMTEC) += i2c-simtec.o obj-$(CONFIG_I2C_SPRD) += i2c-sprd.o diff --git a/drivers/i2c/busses/i2c-sh7760.c b/drivers/i2c/busses/i2c-sh7760.c deleted file mode 100644 index 319d1fa617c883..00000000000000 --- a/drivers/i2c/busses/i2c-sh7760.c +++ /dev/null @@ -1,565 +0,0 @@ -/* - * I2C bus driver for the SH7760 I2C Interfaces. - * - * (c) 2005-2008 MSC Vertriebsges.m.b.H, Manuel Lauss - * - * licensed under the terms outlined in the file COPYING. - * - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -/* register offsets */ -#define I2CSCR 0x0 /* slave ctrl */ -#define I2CMCR 0x4 /* master ctrl */ -#define I2CSSR 0x8 /* slave status */ -#define I2CMSR 0xC /* master status */ -#define I2CSIER 0x10 /* slave irq enable */ -#define I2CMIER 0x14 /* master irq enable */ -#define I2CCCR 0x18 /* clock dividers */ -#define I2CSAR 0x1c /* slave address */ -#define I2CMAR 0x20 /* master address */ -#define I2CRXTX 0x24 /* data port */ -#define I2CFCR 0x28 /* fifo control */ -#define I2CFSR 0x2C /* fifo status */ -#define I2CFIER 0x30 /* fifo irq enable */ -#define I2CRFDR 0x34 /* rx fifo count */ -#define I2CTFDR 0x38 /* tx fifo count */ - -#define REGSIZE 0x3C - -#define MCR_MDBS 0x80 /* non-fifo mode switch */ -#define MCR_FSCL 0x40 /* override SCL pin */ -#define MCR_FSDA 0x20 /* override SDA pin */ -#define MCR_OBPC 0x10 /* override pins */ -#define MCR_MIE 0x08 /* master if enable */ -#define MCR_TSBE 0x04 -#define MCR_FSB 0x02 /* force stop bit */ -#define MCR_ESG 0x01 /* en startbit gen. */ - -#define MSR_MNR 0x40 /* nack received */ -#define MSR_MAL 0x20 /* arbitration lost */ -#define MSR_MST 0x10 /* sent a stop */ -#define MSR_MDE 0x08 -#define MSR_MDT 0x04 -#define MSR_MDR 0x02 -#define MSR_MAT 0x01 /* slave addr xfer done */ - -#define MIE_MNRE 0x40 /* nack irq en */ -#define MIE_MALE 0x20 /* arblos irq en */ -#define MIE_MSTE 0x10 /* stop irq en */ -#define MIE_MDEE 0x08 -#define MIE_MDTE 0x04 -#define MIE_MDRE 0x02 -#define MIE_MATE 0x01 /* address sent irq en */ - -#define FCR_RFRST 0x02 /* reset rx fifo */ -#define FCR_TFRST 0x01 /* reset tx fifo */ - -#define FSR_TEND 0x04 /* last byte sent */ -#define FSR_RDF 0x02 /* rx fifo trigger */ -#define FSR_TDFE 0x01 /* tx fifo empty */ - -#define FIER_TEIE 0x04 /* tx fifo empty irq en */ -#define FIER_RXIE 0x02 /* rx fifo trig irq en */ -#define FIER_TXIE 0x01 /* tx fifo trig irq en */ - -#define FIFO_SIZE 16 - -struct cami2c { - void __iomem *iobase; - struct i2c_adapter adap; - - /* message processing */ - struct i2c_msg *msg; -#define IDF_SEND 1 -#define IDF_RECV 2 -#define IDF_STOP 4 - int flags; - -#define IDS_DONE 1 -#define IDS_ARBLOST 2 -#define IDS_NACK 4 - int status; - struct completion xfer_done; - - int irq; - struct resource *ioarea; -}; - -static inline void OUT32(struct cami2c *cam, int reg, unsigned long val) -{ - __raw_writel(val, (unsigned long)cam->iobase + reg); -} - -static inline unsigned long IN32(struct cami2c *cam, int reg) -{ - return __raw_readl((unsigned long)cam->iobase + reg); -} - -static irqreturn_t sh7760_i2c_irq(int irq, void *ptr) -{ - struct cami2c *id = ptr; - struct i2c_msg *msg = id->msg; - char *data = msg->buf; - unsigned long msr, fsr, fier, len; - - msr = IN32(id, I2CMSR); - fsr = IN32(id, I2CFSR); - - /* arbitration lost */ - if (msr & MSR_MAL) { - OUT32(id, I2CMCR, 0); - OUT32(id, I2CSCR, 0); - OUT32(id, I2CSAR, 0); - id->status |= IDS_DONE | IDS_ARBLOST; - goto out; - } - - if (msr & MSR_MNR) { - /* NACK handling is very screwed up. After receiving a - * NAK IRQ one has to wait a bit before writing to any - * registers, or the ctl will lock up. After that delay - * do a normal i2c stop. Then wait at least 1 ms before - * attempting another transfer or ctl will stop working - */ - udelay(100); /* wait or risk ctl hang */ - OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST); - OUT32(id, I2CMCR, MCR_MIE | MCR_FSB); - OUT32(id, I2CFIER, 0); - OUT32(id, I2CMIER, MIE_MSTE); - OUT32(id, I2CSCR, 0); - OUT32(id, I2CSAR, 0); - id->status |= IDS_NACK; - msr &= ~MSR_MAT; - fsr = 0; - /* In some cases the MST bit is also set. */ - } - - /* i2c-stop was sent */ - if (msr & MSR_MST) { - id->status |= IDS_DONE; - goto out; - } - - /* i2c slave addr was sent; set to "normal" operation */ - if (msr & MSR_MAT) - OUT32(id, I2CMCR, MCR_MIE); - - fier = IN32(id, I2CFIER); - - if (fsr & FSR_RDF) { - len = IN32(id, I2CRFDR); - if (msg->len <= len) { - if (id->flags & IDF_STOP) { - OUT32(id, I2CMCR, MCR_MIE | MCR_FSB); - OUT32(id, I2CFIER, 0); - /* manual says: wait >= 0.5 SCL times */ - udelay(5); - /* next int should be MST */ - } else { - id->status |= IDS_DONE; - /* keep the RDF bit: ctrl holds SCL low - * until the setup for the next i2c_msg - * clears this bit. - */ - fsr &= ~FSR_RDF; - } - } - while (msg->len && len) { - *data++ = IN32(id, I2CRXTX); - msg->len--; - len--; - } - - if (msg->len) { - len = (msg->len >= FIFO_SIZE) ? FIFO_SIZE - 1 - : msg->len - 1; - - OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xf) << 4)); - } - - } else if (id->flags & IDF_SEND) { - if ((fsr & FSR_TEND) && (msg->len < 1)) { - if (id->flags & IDF_STOP) { - OUT32(id, I2CMCR, MCR_MIE | MCR_FSB); - } else { - id->status |= IDS_DONE; - /* keep the TEND bit: ctl holds SCL low - * until the setup for the next i2c_msg - * clears this bit. - */ - fsr &= ~FSR_TEND; - } - } - if (fsr & FSR_TDFE) { - while (msg->len && (IN32(id, I2CTFDR) < FIFO_SIZE)) { - OUT32(id, I2CRXTX, *data++); - msg->len--; - } - - if (msg->len < 1) { - fier &= ~FIER_TXIE; - OUT32(id, I2CFIER, fier); - } else { - len = (msg->len >= FIFO_SIZE) ? 2 : 0; - OUT32(id, I2CFCR, - FCR_RFRST | ((len & 3) << 2)); - } - } - } -out: - if (id->status & IDS_DONE) { - OUT32(id, I2CMIER, 0); - OUT32(id, I2CFIER, 0); - id->msg = NULL; - complete(&id->xfer_done); - } - /* clear status flags and ctrl resumes work */ - OUT32(id, I2CMSR, ~msr); - OUT32(id, I2CFSR, ~fsr); - OUT32(id, I2CSSR, 0); - - return IRQ_HANDLED; -} - - -/* prepare and start a master receive operation */ -static void sh7760_i2c_mrecv(struct cami2c *id) -{ - int len; - - id->flags |= IDF_RECV; - - /* set the slave addr reg; otherwise rcv wont work! */ - OUT32(id, I2CSAR, 0xfe); - OUT32(id, I2CMAR, (id->msg->addr << 1) | 1); - - /* adjust rx fifo trigger */ - if (id->msg->len >= FIFO_SIZE) - len = FIFO_SIZE - 1; /* trigger at fifo full */ - else - len = id->msg->len - 1; /* trigger before all received */ - - OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST); - OUT32(id, I2CFCR, FCR_TFRST | ((len & 0xF) << 4)); - - OUT32(id, I2CMSR, 0); - OUT32(id, I2CMCR, MCR_MIE | MCR_ESG); - OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE); - OUT32(id, I2CFIER, FIER_RXIE); -} - -/* prepare and start a master send operation */ -static void sh7760_i2c_msend(struct cami2c *id) -{ - int len; - - id->flags |= IDF_SEND; - - /* set the slave addr reg; otherwise xmit wont work! */ - OUT32(id, I2CSAR, 0xfe); - OUT32(id, I2CMAR, (id->msg->addr << 1) | 0); - - /* adjust tx fifo trigger */ - if (id->msg->len >= FIFO_SIZE) - len = 2; /* trig: 2 bytes left in TX fifo */ - else - len = 0; /* trig: 8 bytes left in TX fifo */ - - OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST); - OUT32(id, I2CFCR, FCR_RFRST | ((len & 3) << 2)); - - while (id->msg->len && IN32(id, I2CTFDR) < FIFO_SIZE) { - OUT32(id, I2CRXTX, *(id->msg->buf)); - (id->msg->len)--; - (id->msg->buf)++; - } - - OUT32(id, I2CMSR, 0); - OUT32(id, I2CMCR, MCR_MIE | MCR_ESG); - OUT32(id, I2CFSR, 0); - OUT32(id, I2CMIER, MIE_MNRE | MIE_MALE | MIE_MSTE | MIE_MATE); - OUT32(id, I2CFIER, FIER_TEIE | (id->msg->len ? FIER_TXIE : 0)); -} - -static inline int sh7760_i2c_busy_check(struct cami2c *id) -{ - return (IN32(id, I2CMCR) & MCR_FSDA); -} - -static int sh7760_i2c_master_xfer(struct i2c_adapter *adap, - struct i2c_msg *msgs, - int num) -{ - struct cami2c *id = adap->algo_data; - int i, retr; - - if (sh7760_i2c_busy_check(id)) { - dev_err(&adap->dev, "sh7760-i2c%d: bus busy!\n", adap->nr); - return -EBUSY; - } - - i = 0; - while (i < num) { - retr = adap->retries; -retry: - id->flags = ((i == (num-1)) ? IDF_STOP : 0); - id->status = 0; - id->msg = msgs; - init_completion(&id->xfer_done); - - if (msgs->flags & I2C_M_RD) - sh7760_i2c_mrecv(id); - else - sh7760_i2c_msend(id); - - wait_for_completion(&id->xfer_done); - - if (id->status == 0) { - num = -EIO; - break; - } - - if (id->status & IDS_NACK) { - /* wait a bit or i2c module stops working */ - mdelay(1); - num = -EREMOTEIO; - break; - } - - if (id->status & IDS_ARBLOST) { - if (retr--) { - mdelay(2); - goto retry; - } - num = -EREMOTEIO; - break; - } - - msgs++; - i++; - } - - id->msg = NULL; - id->flags = 0; - id->status = 0; - - OUT32(id, I2CMCR, 0); - OUT32(id, I2CMSR, 0); - OUT32(id, I2CMIER, 0); - OUT32(id, I2CFIER, 0); - - /* reset slave module registers too: master mode enables slave - * module for receive ops (ack, data). Without this reset, - * eternal bus activity might be reported after NACK / ARBLOST. - */ - OUT32(id, I2CSCR, 0); - OUT32(id, I2CSAR, 0); - OUT32(id, I2CSSR, 0); - - return num; -} - -static u32 sh7760_i2c_func(struct i2c_adapter *adap) -{ - return I2C_FUNC_I2C | (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK); -} - -static const struct i2c_algorithm sh7760_i2c_algo = { - .master_xfer = sh7760_i2c_master_xfer, - .functionality = sh7760_i2c_func, -}; - -/* calculate CCR register setting for a desired scl clock. SCL clock is - * derived from I2C module clock (iclk) which in turn is derived from - * peripheral module clock (mclk, usually around 33MHz): - * iclk = mclk/(CDF + 1). iclk must be < 20MHz. - * scl = iclk/(SCGD*8 + 20). - */ -static int calc_CCR(unsigned long scl_hz) -{ - struct clk *mclk; - unsigned long mck, m1, dff, odff, iclk; - signed char cdf, cdfm; - int scgd, scgdm, scgds; - - mclk = clk_get(NULL, "peripheral_clk"); - if (IS_ERR(mclk)) { - return PTR_ERR(mclk); - } else { - mck = mclk->rate; - clk_put(mclk); - } - - odff = scl_hz; - scgdm = cdfm = m1 = 0; - for (cdf = 3; cdf >= 0; cdf--) { - iclk = mck / (1 + cdf); - if (iclk >= 20000000) - continue; - scgds = ((iclk / scl_hz) - 20) >> 3; - for (scgd = scgds; (scgd < 63) && scgd <= scgds + 1; scgd++) { - m1 = iclk / (20 + (scgd << 3)); - dff = abs(scl_hz - m1); - if (dff < odff) { - odff = dff; - cdfm = cdf; - scgdm = scgd; - } - } - } - /* fail if more than 25% off of requested SCL */ - if (odff > (scl_hz >> 2)) - return -EINVAL; - - /* create a CCR register value */ - return ((scgdm << 2) | cdfm); -} - -static int sh7760_i2c_probe(struct platform_device *pdev) -{ - struct sh7760_i2c_platdata *pd; - struct resource *res; - struct cami2c *id; - int ret; - - pd = dev_get_platdata(&pdev->dev); - if (!pd) { - dev_err(&pdev->dev, "no platform_data!\n"); - ret = -ENODEV; - goto out0; - } - - id = kzalloc(sizeof(struct cami2c), GFP_KERNEL); - if (!id) { - dev_err(&pdev->dev, "no mem for private data\n"); - ret = -ENOMEM; - goto out0; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no mmio resources\n"); - ret = -ENODEV; - goto out1; - } - - id->ioarea = request_mem_region(res->start, REGSIZE, pdev->name); - if (!id->ioarea) { - dev_err(&pdev->dev, "mmio already reserved\n"); - ret = -EBUSY; - goto out1; - } - - id->iobase = ioremap(res->start, REGSIZE); - if (!id->iobase) { - dev_err(&pdev->dev, "cannot ioremap\n"); - ret = -ENODEV; - goto out2; - } - - ret = platform_get_irq(pdev, 0); - if (ret < 0) - goto out3; - id->irq = ret; - - id->adap.nr = pdev->id; - id->adap.algo = &sh7760_i2c_algo; - id->adap.class = I2C_CLASS_HWMON | I2C_CLASS_SPD; - id->adap.retries = 3; - id->adap.algo_data = id; - id->adap.dev.parent = &pdev->dev; - snprintf(id->adap.name, sizeof(id->adap.name), - "SH7760 I2C at %08lx", (unsigned long)res->start); - - OUT32(id, I2CMCR, 0); - OUT32(id, I2CMSR, 0); - OUT32(id, I2CMIER, 0); - OUT32(id, I2CMAR, 0); - OUT32(id, I2CSIER, 0); - OUT32(id, I2CSAR, 0); - OUT32(id, I2CSCR, 0); - OUT32(id, I2CSSR, 0); - OUT32(id, I2CFIER, 0); - OUT32(id, I2CFCR, FCR_RFRST | FCR_TFRST); - OUT32(id, I2CFSR, 0); - - ret = calc_CCR(pd->speed_khz * 1000); - if (ret < 0) { - dev_err(&pdev->dev, "invalid SCL clock: %dkHz\n", - pd->speed_khz); - goto out3; - } - OUT32(id, I2CCCR, ret); - - if (request_irq(id->irq, sh7760_i2c_irq, 0, - SH7760_I2C_DEVNAME, id)) { - dev_err(&pdev->dev, "cannot get irq %d\n", id->irq); - ret = -EBUSY; - goto out3; - } - - ret = i2c_add_numbered_adapter(&id->adap); - if (ret < 0) - goto out4; - - platform_set_drvdata(pdev, id); - - dev_info(&pdev->dev, "%d kHz mmio %08x irq %d\n", - pd->speed_khz, res->start, id->irq); - - return 0; - -out4: - free_irq(id->irq, id); -out3: - iounmap(id->iobase); -out2: - release_resource(id->ioarea); - kfree(id->ioarea); -out1: - kfree(id); -out0: - return ret; -} - -static int sh7760_i2c_remove(struct platform_device *pdev) -{ - struct cami2c *id = platform_get_drvdata(pdev); - - i2c_del_adapter(&id->adap); - free_irq(id->irq, id); - iounmap(id->iobase); - release_resource(id->ioarea); - kfree(id->ioarea); - kfree(id); - - return 0; -} - -static struct platform_driver sh7760_i2c_drv = { - .driver = { - .name = SH7760_I2C_DEVNAME, - }, - .probe = sh7760_i2c_probe, - .remove = sh7760_i2c_remove, -}; - -module_platform_driver(sh7760_i2c_drv); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("SH7760 I2C bus driver"); -MODULE_AUTHOR("Manuel Lauss "); From patchwork Fri Jan 13 06:23:28 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642272 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01431C61DB3 for ; Fri, 13 Jan 2023 06:27:21 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240647AbjAMG1R (ORCPT ); Fri, 13 Jan 2023 01:27:17 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60784 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S235159AbjAMGZO (ORCPT ); Fri, 13 Jan 2023 01:25:14 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 98D161BC80; Thu, 12 Jan 2023 22:24:32 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: Content-Type:MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc: To:From:Sender:Reply-To:Content-ID:Content-Description; bh=38ZdmqJfgTuYXp252hYJNLrwx/7u8Rttfe81dskbpYQ=; b=Dj8Ylj4feHn2Q8zLgHe5rgnue4 +Vm4CVYWIf5GgWiuDd34sTn24Z9KS8CagJsLTrbaAGo+bdtCyIrisky7SzqaYjkbAz1c+1toHsTAk zERaYr6R0NZ5nfOKzpzl38Jjh5JGvj9SvZker/eCdXizSyP8RqgfDnIniAXtmDVMH7uS77fiAX3MG SMTpMiziU7noj7B6ZdgjWYQQlWq7MWw/9kEYFHlda7dz/cdjMI6+Ambw8HLkOzC8SrnJ51N2nKAWd Tb3WfHSt85OhCsocw3wM+N+0KaffKoBMs+e+RifN/F5Tg3MkBHM7JzPqbG6244GTNfxiRKeL3zNBf l46PQTfg==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUE-000lh7-6c; Fri, 13 Jan 2023 06:24:23 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 11/22] mtd/nand: remove sh_flctl Date: Fri, 13 Jan 2023 07:23:28 +0100 Message-Id: <20230113062339.1909087-12-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/mtd/nand/raw/Kconfig | 8 - drivers/mtd/nand/raw/Makefile | 1 - drivers/mtd/nand/raw/sh_flctl.c | 1234 ------------------------------- include/linux/mtd/sh_flctl.h | 180 ----- 4 files changed, 1423 deletions(-) delete mode 100644 drivers/mtd/nand/raw/sh_flctl.c delete mode 100644 include/linux/mtd/sh_flctl.h diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index 98ea1c9e65c8ef..20a4988ea418d5 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -284,14 +284,6 @@ config MTD_NAND_MXC This enables the driver for the NAND flash controller on the MXC processors. -config MTD_NAND_SH_FLCTL - tristate "Renesas SuperH FLCTL NAND controller" - depends on SUPERH || COMPILE_TEST - depends on HAS_IOMEM - help - Several Renesas SuperH CPU has FLCTL. This option enables support - for NAND Flash using FLCTL. - config MTD_NAND_DAVINCI tristate "DaVinci/Keystone NAND controller" depends on ARCH_DAVINCI || (ARCH_KEYSTONE && TI_AEMIF) || COMPILE_TEST diff --git a/drivers/mtd/nand/raw/Makefile b/drivers/mtd/nand/raw/Makefile index fa1d0012031012..2c6eb25c9d0aae 100644 --- a/drivers/mtd/nand/raw/Makefile +++ b/drivers/mtd/nand/raw/Makefile @@ -33,7 +33,6 @@ obj-$(CONFIG_MTD_NAND_FSL_IFC) += fsl_ifc_nand.o obj-$(CONFIG_MTD_NAND_FSL_UPM) += fsl_upm.o obj-$(CONFIG_MTD_NAND_SLC_LPC32XX) += lpc32xx_slc.o obj-$(CONFIG_MTD_NAND_MLC_LPC32XX) += lpc32xx_mlc.o -obj-$(CONFIG_MTD_NAND_SH_FLCTL) += sh_flctl.o obj-$(CONFIG_MTD_NAND_MXC) += mxc_nand.o obj-$(CONFIG_MTD_NAND_SOCRATES) += socrates_nand.o obj-$(CONFIG_MTD_NAND_TXX9NDFMC) += txx9ndfmc.o diff --git a/drivers/mtd/nand/raw/sh_flctl.c b/drivers/mtd/nand/raw/sh_flctl.c deleted file mode 100644 index a278829469d610..00000000000000 --- a/drivers/mtd/nand/raw/sh_flctl.c +++ /dev/null @@ -1,1234 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * SuperH FLCTL nand controller - * - * Copyright (c) 2008 Renesas Solutions Corp. - * Copyright (c) 2008 Atom Create Engineering Co., Ltd. - * - * Based on fsl_elbc_nand.c, Copyright (c) 2006-2007 Freescale Semiconductor - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -static int flctl_4secc_ooblayout_sp_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - - if (section) - return -ERANGE; - - oobregion->offset = 0; - oobregion->length = chip->ecc.bytes; - - return 0; -} - -static int flctl_4secc_ooblayout_sp_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - if (section) - return -ERANGE; - - oobregion->offset = 12; - oobregion->length = 4; - - return 0; -} - -static const struct mtd_ooblayout_ops flctl_4secc_oob_smallpage_ops = { - .ecc = flctl_4secc_ooblayout_sp_ecc, - .free = flctl_4secc_ooblayout_sp_free, -}; - -static int flctl_4secc_ooblayout_lp_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - - if (section >= chip->ecc.steps) - return -ERANGE; - - oobregion->offset = (section * 16) + 6; - oobregion->length = chip->ecc.bytes; - - return 0; -} - -static int flctl_4secc_ooblayout_lp_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) -{ - struct nand_chip *chip = mtd_to_nand(mtd); - - if (section >= chip->ecc.steps) - return -ERANGE; - - oobregion->offset = section * 16; - oobregion->length = 6; - - if (!section) { - oobregion->offset += 2; - oobregion->length -= 2; - } - - return 0; -} - -static const struct mtd_ooblayout_ops flctl_4secc_oob_largepage_ops = { - .ecc = flctl_4secc_ooblayout_lp_ecc, - .free = flctl_4secc_ooblayout_lp_free, -}; - -static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; - -static struct nand_bbt_descr flctl_4secc_smallpage = { - .offs = 11, - .len = 1, - .pattern = scan_ff_pattern, -}; - -static struct nand_bbt_descr flctl_4secc_largepage = { - .offs = 0, - .len = 2, - .pattern = scan_ff_pattern, -}; - -static void empty_fifo(struct sh_flctl *flctl) -{ - writel(flctl->flintdmacr_base | AC1CLR | AC0CLR, FLINTDMACR(flctl)); - writel(flctl->flintdmacr_base, FLINTDMACR(flctl)); -} - -static void start_translation(struct sh_flctl *flctl) -{ - writeb(TRSTRT, FLTRCR(flctl)); -} - -static void timeout_error(struct sh_flctl *flctl, const char *str) -{ - dev_err(&flctl->pdev->dev, "Timeout occurred in %s\n", str); -} - -static void wait_completion(struct sh_flctl *flctl) -{ - uint32_t timeout = LOOP_TIMEOUT_MAX; - - while (timeout--) { - if (readb(FLTRCR(flctl)) & TREND) { - writeb(0x0, FLTRCR(flctl)); - return; - } - udelay(1); - } - - timeout_error(flctl, __func__); - writeb(0x0, FLTRCR(flctl)); -} - -static void flctl_dma_complete(void *param) -{ - struct sh_flctl *flctl = param; - - complete(&flctl->dma_complete); -} - -static void flctl_release_dma(struct sh_flctl *flctl) -{ - if (flctl->chan_fifo0_rx) { - dma_release_channel(flctl->chan_fifo0_rx); - flctl->chan_fifo0_rx = NULL; - } - if (flctl->chan_fifo0_tx) { - dma_release_channel(flctl->chan_fifo0_tx); - flctl->chan_fifo0_tx = NULL; - } -} - -static void flctl_setup_dma(struct sh_flctl *flctl) -{ - dma_cap_mask_t mask; - struct dma_slave_config cfg; - struct platform_device *pdev = flctl->pdev; - struct sh_flctl_platform_data *pdata = dev_get_platdata(&pdev->dev); - int ret; - - if (!pdata) - return; - - if (pdata->slave_id_fifo0_tx <= 0 || pdata->slave_id_fifo0_rx <= 0) - return; - - /* We can only either use DMA for both Tx and Rx or not use it at all */ - dma_cap_zero(mask); - dma_cap_set(DMA_SLAVE, mask); - - flctl->chan_fifo0_tx = dma_request_channel(mask, shdma_chan_filter, - (void *)(uintptr_t)pdata->slave_id_fifo0_tx); - dev_dbg(&pdev->dev, "%s: TX: got channel %p\n", __func__, - flctl->chan_fifo0_tx); - - if (!flctl->chan_fifo0_tx) - return; - - memset(&cfg, 0, sizeof(cfg)); - cfg.direction = DMA_MEM_TO_DEV; - cfg.dst_addr = flctl->fifo; - cfg.src_addr = 0; - ret = dmaengine_slave_config(flctl->chan_fifo0_tx, &cfg); - if (ret < 0) - goto err; - - flctl->chan_fifo0_rx = dma_request_channel(mask, shdma_chan_filter, - (void *)(uintptr_t)pdata->slave_id_fifo0_rx); - dev_dbg(&pdev->dev, "%s: RX: got channel %p\n", __func__, - flctl->chan_fifo0_rx); - - if (!flctl->chan_fifo0_rx) - goto err; - - cfg.direction = DMA_DEV_TO_MEM; - cfg.dst_addr = 0; - cfg.src_addr = flctl->fifo; - ret = dmaengine_slave_config(flctl->chan_fifo0_rx, &cfg); - if (ret < 0) - goto err; - - init_completion(&flctl->dma_complete); - - return; - -err: - flctl_release_dma(flctl); -} - -static void set_addr(struct mtd_info *mtd, int column, int page_addr) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - uint32_t addr = 0; - - if (column == -1) { - addr = page_addr; /* ERASE1 */ - } else if (page_addr != -1) { - /* SEQIN, READ0, etc.. */ - if (flctl->chip.options & NAND_BUSWIDTH_16) - column >>= 1; - if (flctl->page_size) { - addr = column & 0x0FFF; - addr |= (page_addr & 0xff) << 16; - addr |= ((page_addr >> 8) & 0xff) << 24; - /* big than 128MB */ - if (flctl->rw_ADRCNT == ADRCNT2_E) { - uint32_t addr2; - addr2 = (page_addr >> 16) & 0xff; - writel(addr2, FLADR2(flctl)); - } - } else { - addr = column; - addr |= (page_addr & 0xff) << 8; - addr |= ((page_addr >> 8) & 0xff) << 16; - addr |= ((page_addr >> 16) & 0xff) << 24; - } - } - writel(addr, FLADR(flctl)); -} - -static void wait_rfifo_ready(struct sh_flctl *flctl) -{ - uint32_t timeout = LOOP_TIMEOUT_MAX; - - while (timeout--) { - uint32_t val; - /* check FIFO */ - val = readl(FLDTCNTR(flctl)) >> 16; - if (val & 0xFF) - return; - udelay(1); - } - timeout_error(flctl, __func__); -} - -static void wait_wfifo_ready(struct sh_flctl *flctl) -{ - uint32_t len, timeout = LOOP_TIMEOUT_MAX; - - while (timeout--) { - /* check FIFO */ - len = (readl(FLDTCNTR(flctl)) >> 16) & 0xFF; - if (len >= 4) - return; - udelay(1); - } - timeout_error(flctl, __func__); -} - -static enum flctl_ecc_res_t wait_recfifo_ready - (struct sh_flctl *flctl, int sector_number) -{ - uint32_t timeout = LOOP_TIMEOUT_MAX; - void __iomem *ecc_reg[4]; - int i; - int state = FL_SUCCESS; - uint32_t data, size; - - /* - * First this loops checks in FLDTCNTR if we are ready to read out the - * oob data. This is the case if either all went fine without errors or - * if the bottom part of the loop corrected the errors or marked them as - * uncorrectable and the controller is given time to push the data into - * the FIFO. - */ - while (timeout--) { - /* check if all is ok and we can read out the OOB */ - size = readl(FLDTCNTR(flctl)) >> 24; - if ((size & 0xFF) == 4) - return state; - - /* check if a correction code has been calculated */ - if (!(readl(FL4ECCCR(flctl)) & _4ECCEND)) { - /* - * either we wait for the fifo to be filled or a - * correction pattern is being generated - */ - udelay(1); - continue; - } - - /* check for an uncorrectable error */ - if (readl(FL4ECCCR(flctl)) & _4ECCFA) { - /* check if we face a non-empty page */ - for (i = 0; i < 512; i++) { - if (flctl->done_buff[i] != 0xff) { - state = FL_ERROR; /* can't correct */ - break; - } - } - - if (state == FL_SUCCESS) - dev_dbg(&flctl->pdev->dev, - "reading empty sector %d, ecc error ignored\n", - sector_number); - - writel(0, FL4ECCCR(flctl)); - continue; - } - - /* start error correction */ - ecc_reg[0] = FL4ECCRESULT0(flctl); - ecc_reg[1] = FL4ECCRESULT1(flctl); - ecc_reg[2] = FL4ECCRESULT2(flctl); - ecc_reg[3] = FL4ECCRESULT3(flctl); - - for (i = 0; i < 3; i++) { - uint8_t org; - unsigned int index; - - data = readl(ecc_reg[i]); - - if (flctl->page_size) - index = (512 * sector_number) + - (data >> 16); - else - index = data >> 16; - - org = flctl->done_buff[index]; - flctl->done_buff[index] = org ^ (data & 0xFF); - } - state = FL_REPAIRABLE; - writel(0, FL4ECCCR(flctl)); - } - - timeout_error(flctl, __func__); - return FL_TIMEOUT; /* timeout */ -} - -static void wait_wecfifo_ready(struct sh_flctl *flctl) -{ - uint32_t timeout = LOOP_TIMEOUT_MAX; - uint32_t len; - - while (timeout--) { - /* check FLECFIFO */ - len = (readl(FLDTCNTR(flctl)) >> 24) & 0xFF; - if (len >= 4) - return; - udelay(1); - } - timeout_error(flctl, __func__); -} - -static int flctl_dma_fifo0_transfer(struct sh_flctl *flctl, unsigned long *buf, - int len, enum dma_data_direction dir) -{ - struct dma_async_tx_descriptor *desc = NULL; - struct dma_chan *chan; - enum dma_transfer_direction tr_dir; - dma_addr_t dma_addr; - dma_cookie_t cookie; - uint32_t reg; - int ret = 0; - unsigned long time_left; - - if (dir == DMA_FROM_DEVICE) { - chan = flctl->chan_fifo0_rx; - tr_dir = DMA_DEV_TO_MEM; - } else { - chan = flctl->chan_fifo0_tx; - tr_dir = DMA_MEM_TO_DEV; - } - - dma_addr = dma_map_single(chan->device->dev, buf, len, dir); - - if (!dma_mapping_error(chan->device->dev, dma_addr)) - desc = dmaengine_prep_slave_single(chan, dma_addr, len, - tr_dir, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); - - if (desc) { - reg = readl(FLINTDMACR(flctl)); - reg |= DREQ0EN; - writel(reg, FLINTDMACR(flctl)); - - desc->callback = flctl_dma_complete; - desc->callback_param = flctl; - cookie = dmaengine_submit(desc); - if (dma_submit_error(cookie)) { - ret = dma_submit_error(cookie); - dev_warn(&flctl->pdev->dev, - "DMA submit failed, falling back to PIO\n"); - goto out; - } - - dma_async_issue_pending(chan); - } else { - /* DMA failed, fall back to PIO */ - flctl_release_dma(flctl); - dev_warn(&flctl->pdev->dev, - "DMA failed, falling back to PIO\n"); - ret = -EIO; - goto out; - } - - time_left = - wait_for_completion_timeout(&flctl->dma_complete, - msecs_to_jiffies(3000)); - - if (time_left == 0) { - dmaengine_terminate_all(chan); - dev_err(&flctl->pdev->dev, "wait_for_completion_timeout\n"); - ret = -ETIMEDOUT; - } - -out: - reg = readl(FLINTDMACR(flctl)); - reg &= ~DREQ0EN; - writel(reg, FLINTDMACR(flctl)); - - dma_unmap_single(chan->device->dev, dma_addr, len, dir); - - /* ret == 0 is success */ - return ret; -} - -static void read_datareg(struct sh_flctl *flctl, int offset) -{ - unsigned long data; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; - - wait_completion(flctl); - - data = readl(FLDATAR(flctl)); - *buf = le32_to_cpu(data); -} - -static void read_fiforeg(struct sh_flctl *flctl, int rlen, int offset) -{ - int i, len_4align; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; - - len_4align = (rlen + 3) / 4; - - /* initiate DMA transfer */ - if (flctl->chan_fifo0_rx && rlen >= 32 && - !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_FROM_DEVICE)) - goto convert; /* DMA success */ - - /* do polling transfer */ - for (i = 0; i < len_4align; i++) { - wait_rfifo_ready(flctl); - buf[i] = readl(FLDTFIFO(flctl)); - } - -convert: - for (i = 0; i < len_4align; i++) - buf[i] = be32_to_cpu(buf[i]); -} - -static enum flctl_ecc_res_t read_ecfiforeg - (struct sh_flctl *flctl, uint8_t *buff, int sector) -{ - int i; - enum flctl_ecc_res_t res; - unsigned long *ecc_buf = (unsigned long *)buff; - - res = wait_recfifo_ready(flctl , sector); - - if (res != FL_ERROR) { - for (i = 0; i < 4; i++) { - ecc_buf[i] = readl(FLECFIFO(flctl)); - ecc_buf[i] = be32_to_cpu(ecc_buf[i]); - } - } - - return res; -} - -static void write_fiforeg(struct sh_flctl *flctl, int rlen, - unsigned int offset) -{ - int i, len_4align; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; - - len_4align = (rlen + 3) / 4; - for (i = 0; i < len_4align; i++) { - wait_wfifo_ready(flctl); - writel(cpu_to_be32(buf[i]), FLDTFIFO(flctl)); - } -} - -static void write_ec_fiforeg(struct sh_flctl *flctl, int rlen, - unsigned int offset) -{ - int i, len_4align; - unsigned long *buf = (unsigned long *)&flctl->done_buff[offset]; - - len_4align = (rlen + 3) / 4; - - for (i = 0; i < len_4align; i++) - buf[i] = cpu_to_be32(buf[i]); - - /* initiate DMA transfer */ - if (flctl->chan_fifo0_tx && rlen >= 32 && - !flctl_dma_fifo0_transfer(flctl, buf, rlen, DMA_TO_DEVICE)) - return; /* DMA success */ - - /* do polling transfer */ - for (i = 0; i < len_4align; i++) { - wait_wecfifo_ready(flctl); - writel(buf[i], FLECFIFO(flctl)); - } -} - -static void set_cmd_regs(struct mtd_info *mtd, uint32_t cmd, uint32_t flcmcdr_val) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - uint32_t flcmncr_val = flctl->flcmncr_base & ~SEL_16BIT; - uint32_t flcmdcr_val, addr_len_bytes = 0; - - /* Set SNAND bit if page size is 2048byte */ - if (flctl->page_size) - flcmncr_val |= SNAND_E; - else - flcmncr_val &= ~SNAND_E; - - /* default FLCMDCR val */ - flcmdcr_val = DOCMD1_E | DOADR_E; - - /* Set for FLCMDCR */ - switch (cmd) { - case NAND_CMD_ERASE1: - addr_len_bytes = flctl->erase_ADRCNT; - flcmdcr_val |= DOCMD2_E; - break; - case NAND_CMD_READ0: - case NAND_CMD_READOOB: - case NAND_CMD_RNDOUT: - addr_len_bytes = flctl->rw_ADRCNT; - flcmdcr_val |= CDSRC_E; - if (flctl->chip.options & NAND_BUSWIDTH_16) - flcmncr_val |= SEL_16BIT; - break; - case NAND_CMD_SEQIN: - /* This case is that cmd is READ0 or READ1 or READ00 */ - flcmdcr_val &= ~DOADR_E; /* ONLY execute 1st cmd */ - break; - case NAND_CMD_PAGEPROG: - addr_len_bytes = flctl->rw_ADRCNT; - flcmdcr_val |= DOCMD2_E | CDSRC_E | SELRW; - if (flctl->chip.options & NAND_BUSWIDTH_16) - flcmncr_val |= SEL_16BIT; - break; - case NAND_CMD_READID: - flcmncr_val &= ~SNAND_E; - flcmdcr_val |= CDSRC_E; - addr_len_bytes = ADRCNT_1; - break; - case NAND_CMD_STATUS: - case NAND_CMD_RESET: - flcmncr_val &= ~SNAND_E; - flcmdcr_val &= ~(DOADR_E | DOSR_E); - break; - default: - break; - } - - /* Set address bytes parameter */ - flcmdcr_val |= addr_len_bytes; - - /* Now actually write */ - writel(flcmncr_val, FLCMNCR(flctl)); - writel(flcmdcr_val, FLCMDCR(flctl)); - writel(flcmcdr_val, FLCMCDR(flctl)); -} - -static int flctl_read_page_hwecc(struct nand_chip *chip, uint8_t *buf, - int oob_required, int page) -{ - struct mtd_info *mtd = nand_to_mtd(chip); - - nand_read_page_op(chip, page, 0, buf, mtd->writesize); - if (oob_required) - chip->legacy.read_buf(chip, chip->oob_poi, mtd->oobsize); - return 0; -} - -static int flctl_write_page_hwecc(struct nand_chip *chip, const uint8_t *buf, - int oob_required, int page) -{ - struct mtd_info *mtd = nand_to_mtd(chip); - - nand_prog_page_begin_op(chip, page, 0, buf, mtd->writesize); - chip->legacy.write_buf(chip, chip->oob_poi, mtd->oobsize); - return nand_prog_page_end_op(chip); -} - -static void execmd_read_page_sector(struct mtd_info *mtd, int page_addr) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - int sector, page_sectors; - enum flctl_ecc_res_t ecc_result; - - page_sectors = flctl->page_size ? 4 : 1; - - set_cmd_regs(mtd, NAND_CMD_READ0, - (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); - - writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE | _4ECCCORRECT, - FLCMNCR(flctl)); - writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl)); - writel(page_addr << 2, FLADR(flctl)); - - empty_fifo(flctl); - start_translation(flctl); - - for (sector = 0; sector < page_sectors; sector++) { - read_fiforeg(flctl, 512, 512 * sector); - - ecc_result = read_ecfiforeg(flctl, - &flctl->done_buff[mtd->writesize + 16 * sector], - sector); - - switch (ecc_result) { - case FL_REPAIRABLE: - dev_info(&flctl->pdev->dev, - "applied ecc on page 0x%x", page_addr); - mtd->ecc_stats.corrected++; - break; - case FL_ERROR: - dev_warn(&flctl->pdev->dev, - "page 0x%x contains corrupted data\n", - page_addr); - mtd->ecc_stats.failed++; - break; - default: - ; - } - } - - wait_completion(flctl); - - writel(readl(FLCMNCR(flctl)) & ~(ACM_SACCES_MODE | _4ECCCORRECT), - FLCMNCR(flctl)); -} - -static void execmd_read_oob(struct mtd_info *mtd, int page_addr) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - int page_sectors = flctl->page_size ? 4 : 1; - int i; - - set_cmd_regs(mtd, NAND_CMD_READ0, - (NAND_CMD_READSTART << 8) | NAND_CMD_READ0); - - empty_fifo(flctl); - - for (i = 0; i < page_sectors; i++) { - set_addr(mtd, (512 + 16) * i + 512 , page_addr); - writel(16, FLDTCNTR(flctl)); - - start_translation(flctl); - read_fiforeg(flctl, 16, 16 * i); - wait_completion(flctl); - } -} - -static void execmd_write_page_sector(struct mtd_info *mtd) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - int page_addr = flctl->seqin_page_addr; - int sector, page_sectors; - - page_sectors = flctl->page_size ? 4 : 1; - - set_cmd_regs(mtd, NAND_CMD_PAGEPROG, - (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); - - empty_fifo(flctl); - writel(readl(FLCMNCR(flctl)) | ACM_SACCES_MODE, FLCMNCR(flctl)); - writel(readl(FLCMDCR(flctl)) | page_sectors, FLCMDCR(flctl)); - writel(page_addr << 2, FLADR(flctl)); - start_translation(flctl); - - for (sector = 0; sector < page_sectors; sector++) { - write_fiforeg(flctl, 512, 512 * sector); - write_ec_fiforeg(flctl, 16, mtd->writesize + 16 * sector); - } - - wait_completion(flctl); - writel(readl(FLCMNCR(flctl)) & ~ACM_SACCES_MODE, FLCMNCR(flctl)); -} - -static void execmd_write_oob(struct mtd_info *mtd) -{ - struct sh_flctl *flctl = mtd_to_flctl(mtd); - int page_addr = flctl->seqin_page_addr; - int sector, page_sectors; - - page_sectors = flctl->page_size ? 4 : 1; - - set_cmd_regs(mtd, NAND_CMD_PAGEPROG, - (NAND_CMD_PAGEPROG << 8) | NAND_CMD_SEQIN); - - for (sector = 0; sector < page_sectors; sector++) { - empty_fifo(flctl); - set_addr(mtd, sector * 528 + 512, page_addr); - writel(16, FLDTCNTR(flctl)); /* set read size */ - - start_translation(flctl); - write_fiforeg(flctl, 16, 16 * sector); - wait_completion(flctl); - } -} - -static void flctl_cmdfunc(struct nand_chip *chip, unsigned int command, - int column, int page_addr) -{ - struct mtd_info *mtd = nand_to_mtd(chip); - struct sh_flctl *flctl = mtd_to_flctl(mtd); - uint32_t read_cmd = 0; - - pm_runtime_get_sync(&flctl->pdev->dev); - - flctl->read_bytes = 0; - if (command != NAND_CMD_PAGEPROG) - flctl->index = 0; - - switch (command) { - case NAND_CMD_READ1: - case NAND_CMD_READ0: - if (flctl->hwecc) { - /* read page with hwecc */ - execmd_read_page_sector(mtd, page_addr); - break; - } - if (flctl->page_size) - set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8) - | command); - else - set_cmd_regs(mtd, command, command); - - set_addr(mtd, 0, page_addr); - - flctl->read_bytes = mtd->writesize + mtd->oobsize; - if (flctl->chip.options & NAND_BUSWIDTH_16) - column >>= 1; - flctl->index += column; - goto read_normal_exit; - - case NAND_CMD_READOOB: - if (flctl->hwecc) { - /* read page with hwecc */ - execmd_read_oob(mtd, page_addr); - break; - } - - if (flctl->page_size) { - set_cmd_regs(mtd, command, (NAND_CMD_READSTART << 8) - | NAND_CMD_READ0); - set_addr(mtd, mtd->writesize, page_addr); - } else { - set_cmd_regs(mtd, command, command); - set_addr(mtd, 0, page_addr); - } - flctl->read_bytes = mtd->oobsize; - goto read_normal_exit; - - case NAND_CMD_RNDOUT: - if (flctl->hwecc) - break; - - if (flctl->page_size) - set_cmd_regs(mtd, command, (NAND_CMD_RNDOUTSTART << 8) - | command); - else - set_cmd_regs(mtd, command, command); - - set_addr(mtd, column, 0); - - flctl->read_bytes = mtd->writesize + mtd->oobsize - column; - goto read_normal_exit; - - case NAND_CMD_READID: - set_cmd_regs(mtd, command, command); - - /* READID is always performed using an 8-bit bus */ - if (flctl->chip.options & NAND_BUSWIDTH_16) - column <<= 1; - set_addr(mtd, column, 0); - - flctl->read_bytes = 8; - writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ - empty_fifo(flctl); - start_translation(flctl); - read_fiforeg(flctl, flctl->read_bytes, 0); - wait_completion(flctl); - break; - - case NAND_CMD_ERASE1: - flctl->erase1_page_addr = page_addr; - break; - - case NAND_CMD_ERASE2: - set_cmd_regs(mtd, NAND_CMD_ERASE1, - (command << 8) | NAND_CMD_ERASE1); - set_addr(mtd, -1, flctl->erase1_page_addr); - start_translation(flctl); - wait_completion(flctl); - break; - - case NAND_CMD_SEQIN: - if (!flctl->page_size) { - /* output read command */ - if (column >= mtd->writesize) { - column -= mtd->writesize; - read_cmd = NAND_CMD_READOOB; - } else if (column < 256) { - read_cmd = NAND_CMD_READ0; - } else { - column -= 256; - read_cmd = NAND_CMD_READ1; - } - } - flctl->seqin_column = column; - flctl->seqin_page_addr = page_addr; - flctl->seqin_read_cmd = read_cmd; - break; - - case NAND_CMD_PAGEPROG: - empty_fifo(flctl); - if (!flctl->page_size) { - set_cmd_regs(mtd, NAND_CMD_SEQIN, - flctl->seqin_read_cmd); - set_addr(mtd, -1, -1); - writel(0, FLDTCNTR(flctl)); /* set 0 size */ - start_translation(flctl); - wait_completion(flctl); - } - if (flctl->hwecc) { - /* write page with hwecc */ - if (flctl->seqin_column == mtd->writesize) - execmd_write_oob(mtd); - else if (!flctl->seqin_column) - execmd_write_page_sector(mtd); - else - pr_err("Invalid address !?\n"); - break; - } - set_cmd_regs(mtd, command, (command << 8) | NAND_CMD_SEQIN); - set_addr(mtd, flctl->seqin_column, flctl->seqin_page_addr); - writel(flctl->index, FLDTCNTR(flctl)); /* set write size */ - start_translation(flctl); - write_fiforeg(flctl, flctl->index, 0); - wait_completion(flctl); - break; - - case NAND_CMD_STATUS: - set_cmd_regs(mtd, command, command); - set_addr(mtd, -1, -1); - - flctl->read_bytes = 1; - writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ - start_translation(flctl); - read_datareg(flctl, 0); /* read and end */ - break; - - case NAND_CMD_RESET: - set_cmd_regs(mtd, command, command); - set_addr(mtd, -1, -1); - - writel(0, FLDTCNTR(flctl)); /* set 0 size */ - start_translation(flctl); - wait_completion(flctl); - break; - - default: - break; - } - goto runtime_exit; - -read_normal_exit: - writel(flctl->read_bytes, FLDTCNTR(flctl)); /* set read size */ - empty_fifo(flctl); - start_translation(flctl); - read_fiforeg(flctl, flctl->read_bytes, 0); - wait_completion(flctl); -runtime_exit: - pm_runtime_put_sync(&flctl->pdev->dev); - return; -} - -static void flctl_select_chip(struct nand_chip *chip, int chipnr) -{ - struct sh_flctl *flctl = mtd_to_flctl(nand_to_mtd(chip)); - int ret; - - switch (chipnr) { - case -1: - flctl->flcmncr_base &= ~CE0_ENABLE; - - pm_runtime_get_sync(&flctl->pdev->dev); - writel(flctl->flcmncr_base, FLCMNCR(flctl)); - - if (flctl->qos_request) { - dev_pm_qos_remove_request(&flctl->pm_qos); - flctl->qos_request = 0; - } - - pm_runtime_put_sync(&flctl->pdev->dev); - break; - case 0: - flctl->flcmncr_base |= CE0_ENABLE; - - if (!flctl->qos_request) { - ret = dev_pm_qos_add_request(&flctl->pdev->dev, - &flctl->pm_qos, - DEV_PM_QOS_RESUME_LATENCY, - 100); - if (ret < 0) - dev_err(&flctl->pdev->dev, - "PM QoS request failed: %d\n", ret); - flctl->qos_request = 1; - } - - if (flctl->holden) { - pm_runtime_get_sync(&flctl->pdev->dev); - writel(HOLDEN, FLHOLDCR(flctl)); - pm_runtime_put_sync(&flctl->pdev->dev); - } - break; - default: - BUG(); - } -} - -static void flctl_write_buf(struct nand_chip *chip, const uint8_t *buf, int len) -{ - struct sh_flctl *flctl = mtd_to_flctl(nand_to_mtd(chip)); - - memcpy(&flctl->done_buff[flctl->index], buf, len); - flctl->index += len; -} - -static uint8_t flctl_read_byte(struct nand_chip *chip) -{ - struct sh_flctl *flctl = mtd_to_flctl(nand_to_mtd(chip)); - uint8_t data; - - data = flctl->done_buff[flctl->index]; - flctl->index++; - return data; -} - -static void flctl_read_buf(struct nand_chip *chip, uint8_t *buf, int len) -{ - struct sh_flctl *flctl = mtd_to_flctl(nand_to_mtd(chip)); - - memcpy(buf, &flctl->done_buff[flctl->index], len); - flctl->index += len; -} - -static int flctl_chip_attach_chip(struct nand_chip *chip) -{ - u64 targetsize = nanddev_target_size(&chip->base); - struct mtd_info *mtd = nand_to_mtd(chip); - struct sh_flctl *flctl = mtd_to_flctl(mtd); - - /* - * NAND_BUSWIDTH_16 may have been set by nand_scan_ident(). - * Add the SEL_16BIT flag in flctl->flcmncr_base. - */ - if (chip->options & NAND_BUSWIDTH_16) - flctl->flcmncr_base |= SEL_16BIT; - - if (mtd->writesize == 512) { - flctl->page_size = 0; - if (targetsize > (32 << 20)) { - /* big than 32MB */ - flctl->rw_ADRCNT = ADRCNT_4; - flctl->erase_ADRCNT = ADRCNT_3; - } else if (targetsize > (2 << 16)) { - /* big than 128KB */ - flctl->rw_ADRCNT = ADRCNT_3; - flctl->erase_ADRCNT = ADRCNT_2; - } else { - flctl->rw_ADRCNT = ADRCNT_2; - flctl->erase_ADRCNT = ADRCNT_1; - } - } else { - flctl->page_size = 1; - if (targetsize > (128 << 20)) { - /* big than 128MB */ - flctl->rw_ADRCNT = ADRCNT2_E; - flctl->erase_ADRCNT = ADRCNT_3; - } else if (targetsize > (8 << 16)) { - /* big than 512KB */ - flctl->rw_ADRCNT = ADRCNT_4; - flctl->erase_ADRCNT = ADRCNT_2; - } else { - flctl->rw_ADRCNT = ADRCNT_3; - flctl->erase_ADRCNT = ADRCNT_1; - } - } - - if (flctl->hwecc) { - if (mtd->writesize == 512) { - mtd_set_ooblayout(mtd, &flctl_4secc_oob_smallpage_ops); - chip->badblock_pattern = &flctl_4secc_smallpage; - } else { - mtd_set_ooblayout(mtd, &flctl_4secc_oob_largepage_ops); - chip->badblock_pattern = &flctl_4secc_largepage; - } - - chip->ecc.size = 512; - chip->ecc.bytes = 10; - chip->ecc.strength = 4; - chip->ecc.read_page = flctl_read_page_hwecc; - chip->ecc.write_page = flctl_write_page_hwecc; - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_ON_HOST; - - /* 4 symbols ECC enabled */ - flctl->flcmncr_base |= _4ECCEN; - } else { - chip->ecc.engine_type = NAND_ECC_ENGINE_TYPE_SOFT; - chip->ecc.algo = NAND_ECC_ALGO_HAMMING; - } - - return 0; -} - -static const struct nand_controller_ops flctl_nand_controller_ops = { - .attach_chip = flctl_chip_attach_chip, -}; - -static irqreturn_t flctl_handle_flste(int irq, void *dev_id) -{ - struct sh_flctl *flctl = dev_id; - - dev_err(&flctl->pdev->dev, "flste irq: %x\n", readl(FLINTDMACR(flctl))); - writel(flctl->flintdmacr_base, FLINTDMACR(flctl)); - - return IRQ_HANDLED; -} - -struct flctl_soc_config { - unsigned long flcmncr_val; - unsigned has_hwecc:1; - unsigned use_holden:1; -}; - -static struct flctl_soc_config flctl_sh7372_config = { - .flcmncr_val = CLK_16B_12L_4H | TYPESEL_SET | SHBUSSEL, - .has_hwecc = 1, - .use_holden = 1, -}; - -static const struct of_device_id of_flctl_match[] = { - { .compatible = "renesas,shmobile-flctl-sh7372", - .data = &flctl_sh7372_config }, - {}, -}; -MODULE_DEVICE_TABLE(of, of_flctl_match); - -static struct sh_flctl_platform_data *flctl_parse_dt(struct device *dev) -{ - const struct flctl_soc_config *config; - struct sh_flctl_platform_data *pdata; - - config = of_device_get_match_data(dev); - if (!config) { - dev_err(dev, "%s: no OF configuration attached\n", __func__); - return NULL; - } - - pdata = devm_kzalloc(dev, sizeof(struct sh_flctl_platform_data), - GFP_KERNEL); - if (!pdata) - return NULL; - - /* set SoC specific options */ - pdata->flcmncr_val = config->flcmncr_val; - pdata->has_hwecc = config->has_hwecc; - pdata->use_holden = config->use_holden; - - return pdata; -} - -static int flctl_probe(struct platform_device *pdev) -{ - struct resource *res; - struct sh_flctl *flctl; - struct mtd_info *flctl_mtd; - struct nand_chip *nand; - struct sh_flctl_platform_data *pdata; - int ret; - int irq; - - flctl = devm_kzalloc(&pdev->dev, sizeof(struct sh_flctl), GFP_KERNEL); - if (!flctl) - return -ENOMEM; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - flctl->reg = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(flctl->reg)) - return PTR_ERR(flctl->reg); - flctl->fifo = res->start + 0x24; /* FLDTFIFO */ - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - ret = devm_request_irq(&pdev->dev, irq, flctl_handle_flste, IRQF_SHARED, - "flste", flctl); - if (ret) { - dev_err(&pdev->dev, "request interrupt failed.\n"); - return ret; - } - - if (pdev->dev.of_node) - pdata = flctl_parse_dt(&pdev->dev); - else - pdata = dev_get_platdata(&pdev->dev); - - if (!pdata) { - dev_err(&pdev->dev, "no setup data defined\n"); - return -EINVAL; - } - - platform_set_drvdata(pdev, flctl); - nand = &flctl->chip; - flctl_mtd = nand_to_mtd(nand); - nand_set_flash_node(nand, pdev->dev.of_node); - flctl_mtd->dev.parent = &pdev->dev; - flctl->pdev = pdev; - flctl->hwecc = pdata->has_hwecc; - flctl->holden = pdata->use_holden; - flctl->flcmncr_base = pdata->flcmncr_val; - flctl->flintdmacr_base = flctl->hwecc ? (STERINTE | ECERB) : STERINTE; - - /* Set address of hardware control function */ - /* 20 us command delay time */ - nand->legacy.chip_delay = 20; - - nand->legacy.read_byte = flctl_read_byte; - nand->legacy.write_buf = flctl_write_buf; - nand->legacy.read_buf = flctl_read_buf; - nand->legacy.select_chip = flctl_select_chip; - nand->legacy.cmdfunc = flctl_cmdfunc; - nand->legacy.set_features = nand_get_set_features_notsupp; - nand->legacy.get_features = nand_get_set_features_notsupp; - - if (pdata->flcmncr_val & SEL_16BIT) - nand->options |= NAND_BUSWIDTH_16; - - nand->options |= NAND_BBM_FIRSTPAGE | NAND_BBM_SECONDPAGE; - - pm_runtime_enable(&pdev->dev); - pm_runtime_resume(&pdev->dev); - - flctl_setup_dma(flctl); - - nand->legacy.dummy_controller.ops = &flctl_nand_controller_ops; - ret = nand_scan(nand, 1); - if (ret) - goto err_chip; - - ret = mtd_device_register(flctl_mtd, pdata->parts, pdata->nr_parts); - if (ret) - goto cleanup_nand; - - return 0; - -cleanup_nand: - nand_cleanup(nand); -err_chip: - flctl_release_dma(flctl); - pm_runtime_disable(&pdev->dev); - return ret; -} - -static int flctl_remove(struct platform_device *pdev) -{ - struct sh_flctl *flctl = platform_get_drvdata(pdev); - struct nand_chip *chip = &flctl->chip; - int ret; - - flctl_release_dma(flctl); - ret = mtd_device_unregister(nand_to_mtd(chip)); - WARN_ON(ret); - nand_cleanup(chip); - pm_runtime_disable(&pdev->dev); - - return 0; -} - -static struct platform_driver flctl_driver = { - .remove = flctl_remove, - .driver = { - .name = "sh_flctl", - .of_match_table = of_flctl_match, - }, -}; - -module_platform_driver_probe(flctl_driver, flctl_probe); - -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Yoshihiro Shimoda"); -MODULE_DESCRIPTION("SuperH FLCTL driver"); -MODULE_ALIAS("platform:sh_flctl"); diff --git a/include/linux/mtd/sh_flctl.h b/include/linux/mtd/sh_flctl.h deleted file mode 100644 index 78fc2d4218c808..00000000000000 --- a/include/linux/mtd/sh_flctl.h +++ /dev/null @@ -1,180 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 - * - * SuperH FLCTL nand controller - * - * Copyright © 2008 Renesas Solutions Corp. - */ - -#ifndef __SH_FLCTL_H__ -#define __SH_FLCTL_H__ - -#include -#include -#include -#include -#include - -/* FLCTL registers */ -#define FLCMNCR(f) (f->reg + 0x0) -#define FLCMDCR(f) (f->reg + 0x4) -#define FLCMCDR(f) (f->reg + 0x8) -#define FLADR(f) (f->reg + 0xC) -#define FLADR2(f) (f->reg + 0x3C) -#define FLDATAR(f) (f->reg + 0x10) -#define FLDTCNTR(f) (f->reg + 0x14) -#define FLINTDMACR(f) (f->reg + 0x18) -#define FLBSYTMR(f) (f->reg + 0x1C) -#define FLBSYCNT(f) (f->reg + 0x20) -#define FLDTFIFO(f) (f->reg + 0x24) -#define FLECFIFO(f) (f->reg + 0x28) -#define FLTRCR(f) (f->reg + 0x2C) -#define FLHOLDCR(f) (f->reg + 0x38) -#define FL4ECCRESULT0(f) (f->reg + 0x80) -#define FL4ECCRESULT1(f) (f->reg + 0x84) -#define FL4ECCRESULT2(f) (f->reg + 0x88) -#define FL4ECCRESULT3(f) (f->reg + 0x8C) -#define FL4ECCCR(f) (f->reg + 0x90) -#define FL4ECCCNT(f) (f->reg + 0x94) -#define FLERRADR(f) (f->reg + 0x98) - -/* FLCMNCR control bits */ -#define _4ECCCNTEN (0x1 << 24) -#define _4ECCEN (0x1 << 23) -#define _4ECCCORRECT (0x1 << 22) -#define SHBUSSEL (0x1 << 20) -#define SEL_16BIT (0x1 << 19) -#define SNAND_E (0x1 << 18) /* SNAND (0=512 1=2048)*/ -#define QTSEL_E (0x1 << 17) -#define ENDIAN (0x1 << 16) /* 1 = little endian */ -#define FCKSEL_E (0x1 << 15) -#define ACM_SACCES_MODE (0x01 << 10) -#define NANWF_E (0x1 << 9) -#define SE_D (0x1 << 8) /* Spare area disable */ -#define CE1_ENABLE (0x1 << 4) /* Chip Enable 1 */ -#define CE0_ENABLE (0x1 << 3) /* Chip Enable 0 */ -#define TYPESEL_SET (0x1 << 0) - -/* - * Clock settings using the PULSEx registers from FLCMNCR - * - * Some hardware uses bits called PULSEx instead of FCKSEL_E and QTSEL_E - * to control the clock divider used between the High-Speed Peripheral Clock - * and the FLCTL internal clock. If so, use CLK_8_BIT_xxx for connecting 8 bit - * and CLK_16_BIT_xxx for connecting 16 bit bus bandwith NAND chips. For the 16 - * bit version the divider is seperate for the pulse width of high and low - * signals. - */ -#define PULSE3 (0x1 << 27) -#define PULSE2 (0x1 << 17) -#define PULSE1 (0x1 << 15) -#define PULSE0 (0x1 << 9) -#define CLK_8B_0_5 PULSE1 -#define CLK_8B_1 0x0 -#define CLK_8B_1_5 (PULSE1 | PULSE2) -#define CLK_8B_2 PULSE0 -#define CLK_8B_3 (PULSE0 | PULSE1 | PULSE2) -#define CLK_8B_4 (PULSE0 | PULSE2) -#define CLK_16B_6L_2H PULSE0 -#define CLK_16B_9L_3H (PULSE0 | PULSE1 | PULSE2) -#define CLK_16B_12L_4H (PULSE0 | PULSE2) - -/* FLCMDCR control bits */ -#define ADRCNT2_E (0x1 << 31) /* 5byte address enable */ -#define ADRMD_E (0x1 << 26) /* Sector address access */ -#define CDSRC_E (0x1 << 25) /* Data buffer selection */ -#define DOSR_E (0x1 << 24) /* Status read check */ -#define SELRW (0x1 << 21) /* 0:read 1:write */ -#define DOADR_E (0x1 << 20) /* Address stage execute */ -#define ADRCNT_1 (0x00 << 18) /* Address data bytes: 1byte */ -#define ADRCNT_2 (0x01 << 18) /* Address data bytes: 2byte */ -#define ADRCNT_3 (0x02 << 18) /* Address data bytes: 3byte */ -#define ADRCNT_4 (0x03 << 18) /* Address data bytes: 4byte */ -#define DOCMD2_E (0x1 << 17) /* 2nd cmd stage execute */ -#define DOCMD1_E (0x1 << 16) /* 1st cmd stage execute */ - -/* FLINTDMACR control bits */ -#define ESTERINTE (0x1 << 24) /* ECC error interrupt enable */ -#define AC1CLR (0x1 << 19) /* ECC FIFO clear */ -#define AC0CLR (0x1 << 18) /* Data FIFO clear */ -#define DREQ0EN (0x1 << 16) /* FLDTFIFODMA Request Enable */ -#define ECERB (0x1 << 9) /* ECC error */ -#define STERB (0x1 << 8) /* Status error */ -#define STERINTE (0x1 << 4) /* Status error enable */ - -/* FLTRCR control bits */ -#define TRSTRT (0x1 << 0) /* translation start */ -#define TREND (0x1 << 1) /* translation end */ - -/* - * FLHOLDCR control bits - * - * HOLDEN: Bus Occupancy Enable (inverted) - * Enable this bit when the external bus might be used in between transfers. - * If not set and the bus gets used by other modules, a deadlock occurs. - */ -#define HOLDEN (0x1 << 0) - -/* FL4ECCCR control bits */ -#define _4ECCFA (0x1 << 2) /* 4 symbols correct fault */ -#define _4ECCEND (0x1 << 1) /* 4 symbols end */ -#define _4ECCEXST (0x1 << 0) /* 4 symbols exist */ - -#define LOOP_TIMEOUT_MAX 0x00010000 - -enum flctl_ecc_res_t { - FL_SUCCESS, - FL_REPAIRABLE, - FL_ERROR, - FL_TIMEOUT -}; - -struct dma_chan; - -struct sh_flctl { - struct nand_chip chip; - struct platform_device *pdev; - struct dev_pm_qos_request pm_qos; - void __iomem *reg; - resource_size_t fifo; - - uint8_t done_buff[2048 + 64]; /* max size 2048 + 64 */ - int read_bytes; - unsigned int index; - int seqin_column; /* column in SEQIN cmd */ - int seqin_page_addr; /* page_addr in SEQIN cmd */ - uint32_t seqin_read_cmd; /* read cmd in SEQIN cmd */ - int erase1_page_addr; /* page_addr in ERASE1 cmd */ - uint32_t erase_ADRCNT; /* bits of FLCMDCR in ERASE1 cmd */ - uint32_t rw_ADRCNT; /* bits of FLCMDCR in READ WRITE cmd */ - uint32_t flcmncr_base; /* base value of FLCMNCR */ - uint32_t flintdmacr_base; /* irq enable bits */ - - unsigned page_size:1; /* NAND page size (0 = 512, 1 = 2048) */ - unsigned hwecc:1; /* Hardware ECC (0 = disabled, 1 = enabled) */ - unsigned holden:1; /* Hardware has FLHOLDCR and HOLDEN is set */ - unsigned qos_request:1; /* QoS request to prevent deep power shutdown */ - - /* DMA related objects */ - struct dma_chan *chan_fifo0_rx; - struct dma_chan *chan_fifo0_tx; - struct completion dma_complete; -}; - -struct sh_flctl_platform_data { - struct mtd_partition *parts; - int nr_parts; - unsigned long flcmncr_val; - - unsigned has_hwecc:1; - unsigned use_holden:1; - - unsigned int slave_id_fifo0_tx; - unsigned int slave_id_fifo0_rx; -}; - -static inline struct sh_flctl *mtd_to_flctl(struct mtd_info *mtdinfo) -{ - return container_of(mtd_to_nand(mtdinfo), struct sh_flctl, chip); -} - -#endif /* __SH_FLCTL_H__ */ From patchwork Fri Jan 13 06:23:31 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642266 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 897E6C678DD for ; Fri, 13 Jan 2023 06:29:48 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241258AbjAMG3m (ORCPT ); Fri, 13 Jan 2023 01:29:42 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240703AbjAMG0K (ORCPT ); Fri, 13 Jan 2023 01:26:10 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id C7D4E59FBA; Thu, 12 Jan 2023 22:24:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=UYtxIVSpmMH1XYDAY7FJWv5Cfi/HsfZZkleq/nNm9Uw=; b=FGmCCMVyg/J/LDd53VCAmWvvHd SjKDBgOffbXrp1NTrsMhhHv+fKa003jcLOks15DqfShUdbnxAhNIFRM2NSfl7XNQlFYmA2nIB5pd3 18kopN5bw8wlOYCdnpKB6fCAs/R2kJGbMJgqU6leRj/q7GTrVwrCQlwNcduG7xmi3tJMkH4PGwg8t 5NSqH0Z4uJHNdUoGz9t3t0x8nOR8iL/jB6Iq4fOUMDfkW0fbOoSZotzgCKRxKr7TDB8DCS8psj8ep mpDSvDh9CmgJ7bpf8XvejVWWNoIH413VHBYRgX7Ti7jsugFz8NQa+n4/JrcVIP/PeAFvJm9WU/Rhy 7xT7m2yg==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUQ-000lrU-4y; Fri, 13 Jan 2023 06:24:35 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 14/22] remove drivers/sh Date: Fri, 13 Jan 2023 07:23:31 +0100 Message-Id: <20230113062339.1909087-15-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that arch/sh is removed these drivers are dead code. Signed-off-by: Christoph Hellwig --- drivers/Makefile | 1 - drivers/sh/Kconfig | 6 - drivers/sh/Makefile | 12 - drivers/sh/clk/Makefile | 4 - drivers/sh/clk/core.c | 624 ---------------- drivers/sh/clk/cpg.c | 477 ------------ drivers/sh/intc/Kconfig | 44 -- drivers/sh/intc/Makefile | 6 - drivers/sh/intc/access.c | 246 ------- drivers/sh/intc/balancing.c | 97 --- drivers/sh/intc/chip.c | 211 ------ drivers/sh/intc/core.c | 501 ------------- drivers/sh/intc/handle.c | 306 -------- drivers/sh/intc/internals.h | 191 ----- drivers/sh/intc/irqdomain.c | 68 -- drivers/sh/intc/userimask.c | 84 --- drivers/sh/intc/virq-debugfs.c | 54 -- drivers/sh/intc/virq.c | 269 ------- drivers/sh/maple/Makefile | 4 - drivers/sh/maple/maple.c | 895 ----------------------- drivers/sh/pm_runtime.c | 40 - drivers/sh/superhyway/Makefile | 8 - drivers/sh/superhyway/superhyway-sysfs.c | 54 -- drivers/sh/superhyway/superhyway.c | 234 ------ include/linux/sh_clk.h | 213 ------ include/linux/superhyway.h | 107 --- 26 files changed, 4756 deletions(-) delete mode 100644 drivers/sh/Kconfig delete mode 100644 drivers/sh/Makefile delete mode 100644 drivers/sh/clk/Makefile delete mode 100644 drivers/sh/clk/core.c delete mode 100644 drivers/sh/clk/cpg.c delete mode 100644 drivers/sh/intc/Kconfig delete mode 100644 drivers/sh/intc/Makefile delete mode 100644 drivers/sh/intc/access.c delete mode 100644 drivers/sh/intc/balancing.c delete mode 100644 drivers/sh/intc/chip.c delete mode 100644 drivers/sh/intc/core.c delete mode 100644 drivers/sh/intc/handle.c delete mode 100644 drivers/sh/intc/internals.h delete mode 100644 drivers/sh/intc/irqdomain.c delete mode 100644 drivers/sh/intc/userimask.c delete mode 100644 drivers/sh/intc/virq-debugfs.c delete mode 100644 drivers/sh/intc/virq.c delete mode 100644 drivers/sh/maple/Makefile delete mode 100644 drivers/sh/maple/maple.c delete mode 100644 drivers/sh/pm_runtime.c delete mode 100644 drivers/sh/superhyway/Makefile delete mode 100644 drivers/sh/superhyway/superhyway-sysfs.c delete mode 100644 drivers/sh/superhyway/superhyway.c delete mode 100644 include/linux/sh_clk.h delete mode 100644 include/linux/superhyway.h diff --git a/drivers/Makefile b/drivers/Makefile index bdf1c66141c9bd..b97a69a4c40b91 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -134,7 +134,6 @@ obj-$(CONFIG_NEW_LEDS) += leds/ obj-$(CONFIG_INFINIBAND) += infiniband/ obj-y += firmware/ obj-$(CONFIG_CRYPTO) += crypto/ -obj-$(CONFIG_SUPERH) += sh/ obj-y += clocksource/ obj-$(CONFIG_DCA) += dca/ obj-$(CONFIG_HID) += hid/ diff --git a/drivers/sh/Kconfig b/drivers/sh/Kconfig deleted file mode 100644 index 3588fcc9c0d23b..00000000000000 --- a/drivers/sh/Kconfig +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -menu "SuperH / SH-Mobile Driver Options" - -source "drivers/sh/intc/Kconfig" - -endmenu diff --git a/drivers/sh/Makefile b/drivers/sh/Makefile deleted file mode 100644 index c53262835e85e2..00000000000000 --- a/drivers/sh/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -# -# Makefile for the SuperH specific drivers. -# -obj-$(CONFIG_SH_INTC) += intc/ -ifneq ($(CONFIG_COMMON_CLK),y) -obj-$(CONFIG_HAVE_CLK) += clk/ -endif -obj-$(CONFIG_MAPLE) += maple/ -obj-$(CONFIG_SUPERHYWAY) += superhyway/ - -obj-y += pm_runtime.o diff --git a/drivers/sh/clk/Makefile b/drivers/sh/clk/Makefile deleted file mode 100644 index 0158ff3ba9d544..00000000000000 --- a/drivers/sh/clk/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-y := core.o - -obj-$(CONFIG_SH_CLK_CPG) += cpg.o diff --git a/drivers/sh/clk/core.c b/drivers/sh/clk/core.c deleted file mode 100644 index d996782a710642..00000000000000 --- a/drivers/sh/clk/core.c +++ /dev/null @@ -1,624 +0,0 @@ -/* - * SuperH clock framework - * - * Copyright (C) 2005 - 2010 Paul Mundt - * - * This clock framework is derived from the OMAP version by: - * - * Copyright (C) 2004 - 2008 Nokia Corporation - * Written by Tuukka Tikkanen - * - * Modified for omap shared clock framework by Tony Lindgren - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "clock: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static LIST_HEAD(clock_list); -static DEFINE_SPINLOCK(clock_lock); -static DEFINE_MUTEX(clock_list_sem); - -/* clock disable operations are not passed on to hardware during boot */ -static int allow_disable; - -void clk_rate_table_build(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - int nr_freqs, - struct clk_div_mult_table *src_table, - unsigned long *bitmap) -{ - unsigned long mult, div; - unsigned long freq; - int i; - - clk->nr_freqs = nr_freqs; - - for (i = 0; i < nr_freqs; i++) { - div = 1; - mult = 1; - - if (src_table->divisors && i < src_table->nr_divisors) - div = src_table->divisors[i]; - - if (src_table->multipliers && i < src_table->nr_multipliers) - mult = src_table->multipliers[i]; - - if (!div || !mult || (bitmap && !test_bit(i, bitmap))) - freq = CPUFREQ_ENTRY_INVALID; - else - freq = clk->parent->rate * mult / div; - - freq_table[i].driver_data = i; - freq_table[i].frequency = freq; - } - - /* Termination entry */ - freq_table[i].driver_data = i; - freq_table[i].frequency = CPUFREQ_TABLE_END; -} - -struct clk_rate_round_data; - -struct clk_rate_round_data { - unsigned long rate; - unsigned int min, max; - long (*func)(unsigned int, struct clk_rate_round_data *); - void *arg; -}; - -#define for_each_frequency(pos, r, freq) \ - for (pos = r->min, freq = r->func(pos, r); \ - pos <= r->max; pos++, freq = r->func(pos, r)) \ - if (unlikely(freq == 0)) \ - ; \ - else - -static long clk_rate_round_helper(struct clk_rate_round_data *rounder) -{ - unsigned long rate_error, rate_error_prev = ~0UL; - unsigned long highest, lowest, freq; - long rate_best_fit = -ENOENT; - int i; - - highest = 0; - lowest = ~0UL; - - for_each_frequency(i, rounder, freq) { - if (freq > highest) - highest = freq; - if (freq < lowest) - lowest = freq; - - rate_error = abs(freq - rounder->rate); - if (rate_error < rate_error_prev) { - rate_best_fit = freq; - rate_error_prev = rate_error; - } - - if (rate_error == 0) - break; - } - - if (rounder->rate >= highest) - rate_best_fit = highest; - if (rounder->rate <= lowest) - rate_best_fit = lowest; - - return rate_best_fit; -} - -static long clk_rate_table_iter(unsigned int pos, - struct clk_rate_round_data *rounder) -{ - struct cpufreq_frequency_table *freq_table = rounder->arg; - unsigned long freq = freq_table[pos].frequency; - - if (freq == CPUFREQ_ENTRY_INVALID) - freq = 0; - - return freq; -} - -long clk_rate_table_round(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - unsigned long rate) -{ - struct clk_rate_round_data table_round = { - .min = 0, - .max = clk->nr_freqs - 1, - .func = clk_rate_table_iter, - .arg = freq_table, - .rate = rate, - }; - - if (clk->nr_freqs < 1) - return -ENOSYS; - - return clk_rate_round_helper(&table_round); -} - -static long clk_rate_div_range_iter(unsigned int pos, - struct clk_rate_round_data *rounder) -{ - return clk_get_rate(rounder->arg) / pos; -} - -long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, - unsigned int div_max, unsigned long rate) -{ - struct clk_rate_round_data div_range_round = { - .min = div_min, - .max = div_max, - .func = clk_rate_div_range_iter, - .arg = clk_get_parent(clk), - .rate = rate, - }; - - return clk_rate_round_helper(&div_range_round); -} - -static long clk_rate_mult_range_iter(unsigned int pos, - struct clk_rate_round_data *rounder) -{ - return clk_get_rate(rounder->arg) * pos; -} - -long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min, - unsigned int mult_max, unsigned long rate) -{ - struct clk_rate_round_data mult_range_round = { - .min = mult_min, - .max = mult_max, - .func = clk_rate_mult_range_iter, - .arg = clk_get_parent(clk), - .rate = rate, - }; - - return clk_rate_round_helper(&mult_range_round); -} - -int clk_rate_table_find(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - unsigned long rate) -{ - struct cpufreq_frequency_table *pos; - int idx; - - cpufreq_for_each_valid_entry_idx(pos, freq_table, idx) - if (pos->frequency == rate) - return idx; - - return -ENOENT; -} - -/* Used for clocks that always have same value as the parent clock */ -unsigned long followparent_recalc(struct clk *clk) -{ - return clk->parent ? clk->parent->rate : 0; -} - -int clk_reparent(struct clk *child, struct clk *parent) -{ - list_del_init(&child->sibling); - if (parent) - list_add(&child->sibling, &parent->children); - child->parent = parent; - - return 0; -} - -/* Propagate rate to children */ -void propagate_rate(struct clk *tclk) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &tclk->children, sibling) { - if (clkp->ops && clkp->ops->recalc) - clkp->rate = clkp->ops->recalc(clkp); - - propagate_rate(clkp); - } -} - -static void __clk_disable(struct clk *clk) -{ - if (WARN(!clk->usecount, "Trying to disable clock %p with 0 usecount\n", - clk)) - return; - - if (!(--clk->usecount)) { - if (likely(allow_disable && clk->ops && clk->ops->disable)) - clk->ops->disable(clk); - if (likely(clk->parent)) - __clk_disable(clk->parent); - } -} - -void clk_disable(struct clk *clk) -{ - unsigned long flags; - - if (!clk) - return; - - spin_lock_irqsave(&clock_lock, flags); - __clk_disable(clk); - spin_unlock_irqrestore(&clock_lock, flags); -} -EXPORT_SYMBOL_GPL(clk_disable); - -static int __clk_enable(struct clk *clk) -{ - int ret = 0; - - if (clk->usecount++ == 0) { - if (clk->parent) { - ret = __clk_enable(clk->parent); - if (unlikely(ret)) - goto err; - } - - if (clk->ops && clk->ops->enable) { - ret = clk->ops->enable(clk); - if (ret) { - if (clk->parent) - __clk_disable(clk->parent); - goto err; - } - } - } - - return ret; -err: - clk->usecount--; - return ret; -} - -int clk_enable(struct clk *clk) -{ - unsigned long flags; - int ret; - - if (!clk) - return -EINVAL; - - spin_lock_irqsave(&clock_lock, flags); - ret = __clk_enable(clk); - spin_unlock_irqrestore(&clock_lock, flags); - - return ret; -} -EXPORT_SYMBOL_GPL(clk_enable); - -static LIST_HEAD(root_clks); - -/** - * recalculate_root_clocks - recalculate and propagate all root clocks - * - * Recalculates all root clocks (clocks with no parent), which if the - * clock's .recalc is set correctly, should also propagate their rates. - * Called at init. - */ -void recalculate_root_clocks(void) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &root_clks, sibling) { - if (clkp->ops && clkp->ops->recalc) - clkp->rate = clkp->ops->recalc(clkp); - propagate_rate(clkp); - } -} - -static struct clk_mapping dummy_mapping; - -static struct clk *lookup_root_clock(struct clk *clk) -{ - while (clk->parent) - clk = clk->parent; - - return clk; -} - -static int clk_establish_mapping(struct clk *clk) -{ - struct clk_mapping *mapping = clk->mapping; - - /* - * Propagate mappings. - */ - if (!mapping) { - struct clk *clkp; - - /* - * dummy mapping for root clocks with no specified ranges - */ - if (!clk->parent) { - clk->mapping = &dummy_mapping; - goto out; - } - - /* - * If we're on a child clock and it provides no mapping of its - * own, inherit the mapping from its root clock. - */ - clkp = lookup_root_clock(clk); - mapping = clkp->mapping; - BUG_ON(!mapping); - } - - /* - * Establish initial mapping. - */ - if (!mapping->base && mapping->phys) { - kref_init(&mapping->ref); - - mapping->base = ioremap(mapping->phys, mapping->len); - if (unlikely(!mapping->base)) - return -ENXIO; - } else if (mapping->base) { - /* - * Bump the refcount for an existing mapping - */ - kref_get(&mapping->ref); - } - - clk->mapping = mapping; -out: - clk->mapped_reg = clk->mapping->base; - clk->mapped_reg += (phys_addr_t)clk->enable_reg - clk->mapping->phys; - return 0; -} - -static void clk_destroy_mapping(struct kref *kref) -{ - struct clk_mapping *mapping; - - mapping = container_of(kref, struct clk_mapping, ref); - - iounmap(mapping->base); -} - -static void clk_teardown_mapping(struct clk *clk) -{ - struct clk_mapping *mapping = clk->mapping; - - /* Nothing to do */ - if (mapping == &dummy_mapping) - goto out; - - kref_put(&mapping->ref, clk_destroy_mapping); - clk->mapping = NULL; -out: - clk->mapped_reg = NULL; -} - -int clk_register(struct clk *clk) -{ - int ret; - - if (IS_ERR_OR_NULL(clk)) - return -EINVAL; - - /* - * trap out already registered clocks - */ - if (clk->node.next || clk->node.prev) - return 0; - - mutex_lock(&clock_list_sem); - - INIT_LIST_HEAD(&clk->children); - clk->usecount = 0; - - ret = clk_establish_mapping(clk); - if (unlikely(ret)) - goto out_unlock; - - if (clk->parent) - list_add(&clk->sibling, &clk->parent->children); - else - list_add(&clk->sibling, &root_clks); - - list_add(&clk->node, &clock_list); - -#ifdef CONFIG_SH_CLK_CPG_LEGACY - if (clk->ops && clk->ops->init) - clk->ops->init(clk); -#endif - -out_unlock: - mutex_unlock(&clock_list_sem); - - return ret; -} -EXPORT_SYMBOL_GPL(clk_register); - -void clk_unregister(struct clk *clk) -{ - mutex_lock(&clock_list_sem); - list_del(&clk->sibling); - list_del(&clk->node); - clk_teardown_mapping(clk); - mutex_unlock(&clock_list_sem); -} -EXPORT_SYMBOL_GPL(clk_unregister); - -void clk_enable_init_clocks(void) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &clock_list, node) - if (clkp->flags & CLK_ENABLE_ON_INIT) - clk_enable(clkp); -} - -unsigned long clk_get_rate(struct clk *clk) -{ - if (!clk) - return 0; - - return clk->rate; -} -EXPORT_SYMBOL_GPL(clk_get_rate); - -int clk_set_rate(struct clk *clk, unsigned long rate) -{ - int ret = -EOPNOTSUPP; - unsigned long flags; - - if (!clk) - return 0; - - spin_lock_irqsave(&clock_lock, flags); - - if (likely(clk->ops && clk->ops->set_rate)) { - ret = clk->ops->set_rate(clk, rate); - if (ret != 0) - goto out_unlock; - } else { - clk->rate = rate; - ret = 0; - } - - if (clk->ops && clk->ops->recalc) - clk->rate = clk->ops->recalc(clk); - - propagate_rate(clk); - -out_unlock: - spin_unlock_irqrestore(&clock_lock, flags); - - return ret; -} -EXPORT_SYMBOL_GPL(clk_set_rate); - -int clk_set_parent(struct clk *clk, struct clk *parent) -{ - unsigned long flags; - int ret = -EINVAL; - - if (!parent || !clk) - return ret; - if (clk->parent == parent) - return 0; - - spin_lock_irqsave(&clock_lock, flags); - if (clk->usecount == 0) { - if (clk->ops->set_parent) - ret = clk->ops->set_parent(clk, parent); - else - ret = clk_reparent(clk, parent); - - if (ret == 0) { - if (clk->ops->recalc) - clk->rate = clk->ops->recalc(clk); - pr_debug("set parent of %p to %p (new rate %ld)\n", - clk, clk->parent, clk->rate); - propagate_rate(clk); - } - } else - ret = -EBUSY; - spin_unlock_irqrestore(&clock_lock, flags); - - return ret; -} -EXPORT_SYMBOL_GPL(clk_set_parent); - -struct clk *clk_get_parent(struct clk *clk) -{ - if (!clk) - return NULL; - - return clk->parent; -} -EXPORT_SYMBOL_GPL(clk_get_parent); - -long clk_round_rate(struct clk *clk, unsigned long rate) -{ - if (!clk) - return 0; - - if (likely(clk->ops && clk->ops->round_rate)) { - unsigned long flags, rounded; - - spin_lock_irqsave(&clock_lock, flags); - rounded = clk->ops->round_rate(clk, rate); - spin_unlock_irqrestore(&clock_lock, flags); - - return rounded; - } - - return clk_get_rate(clk); -} -EXPORT_SYMBOL_GPL(clk_round_rate); - -#ifdef CONFIG_PM -static void clks_core_resume(void) -{ - struct clk *clkp; - - list_for_each_entry(clkp, &clock_list, node) { - if (likely(clkp->usecount && clkp->ops)) { - unsigned long rate = clkp->rate; - - if (likely(clkp->ops->set_parent)) - clkp->ops->set_parent(clkp, - clkp->parent); - if (likely(clkp->ops->set_rate)) - clkp->ops->set_rate(clkp, rate); - else if (likely(clkp->ops->recalc)) - clkp->rate = clkp->ops->recalc(clkp); - } - } -} - -static struct syscore_ops clks_syscore_ops = { - .resume = clks_core_resume, -}; - -static int __init clk_syscore_init(void) -{ - register_syscore_ops(&clks_syscore_ops); - - return 0; -} -subsys_initcall(clk_syscore_init); -#endif - -static int __init clk_late_init(void) -{ - unsigned long flags; - struct clk *clk; - - /* disable all clocks with zero use count */ - mutex_lock(&clock_list_sem); - spin_lock_irqsave(&clock_lock, flags); - - list_for_each_entry(clk, &clock_list, node) - if (!clk->usecount && clk->ops && clk->ops->disable) - clk->ops->disable(clk); - - /* from now on allow clock disable operations */ - allow_disable = 1; - - spin_unlock_irqrestore(&clock_lock, flags); - mutex_unlock(&clock_list_sem); - return 0; -} -late_initcall(clk_late_init); diff --git a/drivers/sh/clk/cpg.c b/drivers/sh/clk/cpg.c deleted file mode 100644 index fd72d9088bdcbc..00000000000000 --- a/drivers/sh/clk/cpg.c +++ /dev/null @@ -1,477 +0,0 @@ -/* - * Helper routines for SuperH Clock Pulse Generator blocks (CPG). - * - * Copyright (C) 2010 Magnus Damm - * Copyright (C) 2010 - 2012 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include - -#define CPG_CKSTP_BIT BIT(8) - -static unsigned int sh_clk_read(struct clk *clk) -{ - if (clk->flags & CLK_ENABLE_REG_8BIT) - return ioread8(clk->mapped_reg); - else if (clk->flags & CLK_ENABLE_REG_16BIT) - return ioread16(clk->mapped_reg); - - return ioread32(clk->mapped_reg); -} - -static void sh_clk_write(int value, struct clk *clk) -{ - if (clk->flags & CLK_ENABLE_REG_8BIT) - iowrite8(value, clk->mapped_reg); - else if (clk->flags & CLK_ENABLE_REG_16BIT) - iowrite16(value, clk->mapped_reg); - else - iowrite32(value, clk->mapped_reg); -} - -static int sh_clk_mstp_enable(struct clk *clk) -{ - sh_clk_write(sh_clk_read(clk) & ~(1 << clk->enable_bit), clk); - if (clk->status_reg) { - unsigned int (*read)(const void __iomem *addr); - int i; - void __iomem *mapped_status = (phys_addr_t)clk->status_reg - - (phys_addr_t)clk->enable_reg + clk->mapped_reg; - - if (clk->flags & CLK_ENABLE_REG_8BIT) - read = ioread8; - else if (clk->flags & CLK_ENABLE_REG_16BIT) - read = ioread16; - else - read = ioread32; - - for (i = 1000; - (read(mapped_status) & (1 << clk->enable_bit)) && i; - i--) - cpu_relax(); - if (!i) { - pr_err("cpg: failed to enable %p[%d]\n", - clk->enable_reg, clk->enable_bit); - return -ETIMEDOUT; - } - } - return 0; -} - -static void sh_clk_mstp_disable(struct clk *clk) -{ - sh_clk_write(sh_clk_read(clk) | (1 << clk->enable_bit), clk); -} - -static struct sh_clk_ops sh_clk_mstp_clk_ops = { - .enable = sh_clk_mstp_enable, - .disable = sh_clk_mstp_disable, - .recalc = followparent_recalc, -}; - -int __init sh_clk_mstp_register(struct clk *clks, int nr) -{ - struct clk *clkp; - int ret = 0; - int k; - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - clkp->ops = &sh_clk_mstp_clk_ops; - ret |= clk_register(clkp); - } - - return ret; -} - -/* - * Div/mult table lookup helpers - */ -static inline struct clk_div_table *clk_to_div_table(struct clk *clk) -{ - return clk->priv; -} - -static inline struct clk_div_mult_table *clk_to_div_mult_table(struct clk *clk) -{ - return clk_to_div_table(clk)->div_mult_table; -} - -/* - * Common div ops - */ -static long sh_clk_div_round_rate(struct clk *clk, unsigned long rate) -{ - return clk_rate_table_round(clk, clk->freq_table, rate); -} - -static unsigned long sh_clk_div_recalc(struct clk *clk) -{ - struct clk_div_mult_table *table = clk_to_div_mult_table(clk); - unsigned int idx; - - clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, clk->arch_flags ? &clk->arch_flags : NULL); - - idx = (sh_clk_read(clk) >> clk->enable_bit) & clk->div_mask; - - return clk->freq_table[idx].frequency; -} - -static int sh_clk_div_set_rate(struct clk *clk, unsigned long rate) -{ - struct clk_div_table *dt = clk_to_div_table(clk); - unsigned long value; - int idx; - - idx = clk_rate_table_find(clk, clk->freq_table, rate); - if (idx < 0) - return idx; - - value = sh_clk_read(clk); - value &= ~(clk->div_mask << clk->enable_bit); - value |= (idx << clk->enable_bit); - sh_clk_write(value, clk); - - /* XXX: Should use a post-change notifier */ - if (dt->kick) - dt->kick(clk); - - return 0; -} - -static int sh_clk_div_enable(struct clk *clk) -{ - if (clk->div_mask == SH_CLK_DIV6_MSK) { - int ret = sh_clk_div_set_rate(clk, clk->rate); - if (ret < 0) - return ret; - } - - sh_clk_write(sh_clk_read(clk) & ~CPG_CKSTP_BIT, clk); - return 0; -} - -static void sh_clk_div_disable(struct clk *clk) -{ - unsigned int val; - - val = sh_clk_read(clk); - val |= CPG_CKSTP_BIT; - - /* - * div6 clocks require the divisor field to be non-zero or the - * above CKSTP toggle silently fails. Ensure that the divisor - * array is reset to its initial state on disable. - */ - if (clk->flags & CLK_MASK_DIV_ON_DISABLE) - val |= clk->div_mask; - - sh_clk_write(val, clk); -} - -static struct sh_clk_ops sh_clk_div_clk_ops = { - .recalc = sh_clk_div_recalc, - .set_rate = sh_clk_div_set_rate, - .round_rate = sh_clk_div_round_rate, -}; - -static struct sh_clk_ops sh_clk_div_enable_clk_ops = { - .recalc = sh_clk_div_recalc, - .set_rate = sh_clk_div_set_rate, - .round_rate = sh_clk_div_round_rate, - .enable = sh_clk_div_enable, - .disable = sh_clk_div_disable, -}; - -static int __init sh_clk_init_parent(struct clk *clk) -{ - u32 val; - - if (clk->parent) - return 0; - - if (!clk->parent_table || !clk->parent_num) - return 0; - - if (!clk->src_width) { - pr_err("sh_clk_init_parent: cannot select parent clock\n"); - return -EINVAL; - } - - val = (sh_clk_read(clk) >> clk->src_shift); - val &= (1 << clk->src_width) - 1; - - if (val >= clk->parent_num) { - pr_err("sh_clk_init_parent: parent table size failed\n"); - return -EINVAL; - } - - clk_reparent(clk, clk->parent_table[val]); - if (!clk->parent) { - pr_err("sh_clk_init_parent: unable to set parent"); - return -EINVAL; - } - - return 0; -} - -static int __init sh_clk_div_register_ops(struct clk *clks, int nr, - struct clk_div_table *table, struct sh_clk_ops *ops) -{ - struct clk *clkp; - void *freq_table; - int nr_divs = table->div_mult_table->nr_divisors; - int freq_table_size = sizeof(struct cpufreq_frequency_table); - int ret = 0; - int k; - - freq_table_size *= (nr_divs + 1); - freq_table = kcalloc(nr, freq_table_size, GFP_KERNEL); - if (!freq_table) { - pr_err("%s: unable to alloc memory\n", __func__); - return -ENOMEM; - } - - for (k = 0; !ret && (k < nr); k++) { - clkp = clks + k; - - clkp->ops = ops; - clkp->priv = table; - - clkp->freq_table = freq_table + (k * freq_table_size); - clkp->freq_table[nr_divs].frequency = CPUFREQ_TABLE_END; - - ret = clk_register(clkp); - if (ret == 0) - ret = sh_clk_init_parent(clkp); - } - - return ret; -} - -/* - * div6 support - */ -static int sh_clk_div6_divisors[64] = { - 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, - 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64 -}; - -static struct clk_div_mult_table div6_div_mult_table = { - .divisors = sh_clk_div6_divisors, - .nr_divisors = ARRAY_SIZE(sh_clk_div6_divisors), -}; - -static struct clk_div_table sh_clk_div6_table = { - .div_mult_table = &div6_div_mult_table, -}; - -static int sh_clk_div6_set_parent(struct clk *clk, struct clk *parent) -{ - struct clk_div_mult_table *table = clk_to_div_mult_table(clk); - u32 value; - int ret, i; - - if (!clk->parent_table || !clk->parent_num) - return -EINVAL; - - /* Search the parent */ - for (i = 0; i < clk->parent_num; i++) - if (clk->parent_table[i] == parent) - break; - - if (i == clk->parent_num) - return -ENODEV; - - ret = clk_reparent(clk, parent); - if (ret < 0) - return ret; - - value = sh_clk_read(clk) & - ~(((1 << clk->src_width) - 1) << clk->src_shift); - - sh_clk_write(value | (i << clk->src_shift), clk); - - /* Rebuild the frequency table */ - clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, NULL); - - return 0; -} - -static struct sh_clk_ops sh_clk_div6_reparent_clk_ops = { - .recalc = sh_clk_div_recalc, - .round_rate = sh_clk_div_round_rate, - .set_rate = sh_clk_div_set_rate, - .enable = sh_clk_div_enable, - .disable = sh_clk_div_disable, - .set_parent = sh_clk_div6_set_parent, -}; - -int __init sh_clk_div6_register(struct clk *clks, int nr) -{ - return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table, - &sh_clk_div_enable_clk_ops); -} - -int __init sh_clk_div6_reparent_register(struct clk *clks, int nr) -{ - return sh_clk_div_register_ops(clks, nr, &sh_clk_div6_table, - &sh_clk_div6_reparent_clk_ops); -} - -/* - * div4 support - */ -static int sh_clk_div4_set_parent(struct clk *clk, struct clk *parent) -{ - struct clk_div_mult_table *table = clk_to_div_mult_table(clk); - u32 value; - int ret; - - /* we really need a better way to determine parent index, but for - * now assume internal parent comes with CLK_ENABLE_ON_INIT set, - * no CLK_ENABLE_ON_INIT means external clock... - */ - - if (parent->flags & CLK_ENABLE_ON_INIT) - value = sh_clk_read(clk) & ~(1 << 7); - else - value = sh_clk_read(clk) | (1 << 7); - - ret = clk_reparent(clk, parent); - if (ret < 0) - return ret; - - sh_clk_write(value, clk); - - /* Rebiuld the frequency table */ - clk_rate_table_build(clk, clk->freq_table, table->nr_divisors, - table, &clk->arch_flags); - - return 0; -} - -static struct sh_clk_ops sh_clk_div4_reparent_clk_ops = { - .recalc = sh_clk_div_recalc, - .set_rate = sh_clk_div_set_rate, - .round_rate = sh_clk_div_round_rate, - .enable = sh_clk_div_enable, - .disable = sh_clk_div_disable, - .set_parent = sh_clk_div4_set_parent, -}; - -int __init sh_clk_div4_register(struct clk *clks, int nr, - struct clk_div4_table *table) -{ - return sh_clk_div_register_ops(clks, nr, table, &sh_clk_div_clk_ops); -} - -int __init sh_clk_div4_enable_register(struct clk *clks, int nr, - struct clk_div4_table *table) -{ - return sh_clk_div_register_ops(clks, nr, table, - &sh_clk_div_enable_clk_ops); -} - -int __init sh_clk_div4_reparent_register(struct clk *clks, int nr, - struct clk_div4_table *table) -{ - return sh_clk_div_register_ops(clks, nr, table, - &sh_clk_div4_reparent_clk_ops); -} - -/* FSI-DIV */ -static unsigned long fsidiv_recalc(struct clk *clk) -{ - u32 value; - - value = __raw_readl(clk->mapping->base); - - value >>= 16; - if (value < 2) - return clk->parent->rate; - - return clk->parent->rate / value; -} - -static long fsidiv_round_rate(struct clk *clk, unsigned long rate) -{ - return clk_rate_div_range_round(clk, 1, 0xffff, rate); -} - -static void fsidiv_disable(struct clk *clk) -{ - __raw_writel(0, clk->mapping->base); -} - -static int fsidiv_enable(struct clk *clk) -{ - u32 value; - - value = __raw_readl(clk->mapping->base) >> 16; - if (value < 2) - return 0; - - __raw_writel((value << 16) | 0x3, clk->mapping->base); - - return 0; -} - -static int fsidiv_set_rate(struct clk *clk, unsigned long rate) -{ - int idx; - - idx = (clk->parent->rate / rate) & 0xffff; - if (idx < 2) - __raw_writel(0, clk->mapping->base); - else - __raw_writel(idx << 16, clk->mapping->base); - - return 0; -} - -static struct sh_clk_ops fsidiv_clk_ops = { - .recalc = fsidiv_recalc, - .round_rate = fsidiv_round_rate, - .set_rate = fsidiv_set_rate, - .enable = fsidiv_enable, - .disable = fsidiv_disable, -}; - -int __init sh_clk_fsidiv_register(struct clk *clks, int nr) -{ - struct clk_mapping *map; - int i; - - for (i = 0; i < nr; i++) { - - map = kzalloc(sizeof(struct clk_mapping), GFP_KERNEL); - if (!map) { - pr_err("%s: unable to alloc memory\n", __func__); - return -ENOMEM; - } - - /* clks[i].enable_reg came from SH_CLK_FSIDIV() */ - map->phys = (phys_addr_t)clks[i].enable_reg; - map->len = 8; - - clks[i].enable_reg = 0; /* remove .enable_reg */ - clks[i].ops = &fsidiv_clk_ops; - clks[i].mapping = map; - - clk_register(&clks[i]); - } - - return 0; -} diff --git a/drivers/sh/intc/Kconfig b/drivers/sh/intc/Kconfig deleted file mode 100644 index 5c701709fef528..00000000000000 --- a/drivers/sh/intc/Kconfig +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -config SH_INTC - bool - select IRQ_DOMAIN - -if SH_INTC - -comment "Interrupt controller options" - -config INTC_USERIMASK - bool "Userspace interrupt masking support" - depends on (SUPERH && CPU_SH4A) || COMPILE_TEST - help - This enables support for hardware-assisted userspace hardirq - masking. - - SH-4A and newer interrupt blocks all support a special shadowed - page with all non-masking registers obscured when mapped in to - userspace. This is primarily for use by userspace device - drivers that are using special priority levels. - - If in doubt, say N. - -config INTC_BALANCING - bool "Hardware IRQ balancing support" - depends on SMP && SUPERH && CPU_SHX3 - help - This enables support for IRQ auto-distribution mode on SH-X3 - SMP parts. All of the balancing and CPU wakeup decisions are - taken care of automatically by hardware for distributed - vectors. - - If in doubt, say N. - -config INTC_MAPPING_DEBUG - bool "Expose IRQ to per-controller id mapping via debugfs" - depends on DEBUG_FS - help - This will create a debugfs entry for showing the relationship - between system IRQs and the per-controller id tables. - - If in doubt, say N. - -endif diff --git a/drivers/sh/intc/Makefile b/drivers/sh/intc/Makefile deleted file mode 100644 index bdd855327e41d5..00000000000000 --- a/drivers/sh/intc/Makefile +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -obj-y := access.o chip.o core.o handle.o irqdomain.o virq.o - -obj-$(CONFIG_INTC_BALANCING) += balancing.o -obj-$(CONFIG_INTC_USERIMASK) += userimask.o -obj-$(CONFIG_INTC_MAPPING_DEBUG) += virq-debugfs.o diff --git a/drivers/sh/intc/access.c b/drivers/sh/intc/access.c deleted file mode 100644 index 114390f967d26e..00000000000000 --- a/drivers/sh/intc/access.c +++ /dev/null @@ -1,246 +0,0 @@ -/* - * Common INTC2 register accessors - * - * Copyright (C) 2007, 2008 Magnus Damm - * Copyright (C) 2009, 2010 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include "internals.h" - -unsigned long intc_phys_to_virt(struct intc_desc_int *d, unsigned long address) -{ - struct intc_window *window; - int k; - - /* scan through physical windows and convert address */ - for (k = 0; k < d->nr_windows; k++) { - window = d->window + k; - - if (address < window->phys) - continue; - - if (address >= (window->phys + window->size)) - continue; - - address -= window->phys; - address += (unsigned long)window->virt; - - return address; - } - - /* no windows defined, register must be 1:1 mapped virt:phys */ - return address; -} - -unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address) -{ - unsigned int k; - - address = intc_phys_to_virt(d, address); - - for (k = 0; k < d->nr_reg; k++) { - if (d->reg[k] == address) - return k; - } - - BUG(); - return 0; -} - -unsigned int intc_set_field_from_handle(unsigned int value, - unsigned int field_value, - unsigned int handle) -{ - unsigned int width = _INTC_WIDTH(handle); - unsigned int shift = _INTC_SHIFT(handle); - - value &= ~(((1 << width) - 1) << shift); - value |= field_value << shift; - return value; -} - -unsigned long intc_get_field_from_handle(unsigned int value, unsigned int handle) -{ - unsigned int width = _INTC_WIDTH(handle); - unsigned int shift = _INTC_SHIFT(handle); - unsigned int mask = ((1 << width) - 1) << shift; - - return (value & mask) >> shift; -} - -static unsigned long test_8(unsigned long addr, unsigned long h, - unsigned long ignore) -{ - void __iomem *ptr = (void __iomem *)addr; - return intc_get_field_from_handle(__raw_readb(ptr), h); -} - -static unsigned long test_16(unsigned long addr, unsigned long h, - unsigned long ignore) -{ - void __iomem *ptr = (void __iomem *)addr; - return intc_get_field_from_handle(__raw_readw(ptr), h); -} - -static unsigned long test_32(unsigned long addr, unsigned long h, - unsigned long ignore) -{ - void __iomem *ptr = (void __iomem *)addr; - return intc_get_field_from_handle(__raw_readl(ptr), h); -} - -static unsigned long write_8(unsigned long addr, unsigned long h, - unsigned long data) -{ - void __iomem *ptr = (void __iomem *)addr; - __raw_writeb(intc_set_field_from_handle(0, data, h), ptr); - (void)__raw_readb(ptr); /* Defeat write posting */ - return 0; -} - -static unsigned long write_16(unsigned long addr, unsigned long h, - unsigned long data) -{ - void __iomem *ptr = (void __iomem *)addr; - __raw_writew(intc_set_field_from_handle(0, data, h), ptr); - (void)__raw_readw(ptr); /* Defeat write posting */ - return 0; -} - -static unsigned long write_32(unsigned long addr, unsigned long h, - unsigned long data) -{ - void __iomem *ptr = (void __iomem *)addr; - __raw_writel(intc_set_field_from_handle(0, data, h), ptr); - (void)__raw_readl(ptr); /* Defeat write posting */ - return 0; -} - -static unsigned long modify_8(unsigned long addr, unsigned long h, - unsigned long data) -{ - void __iomem *ptr = (void __iomem *)addr; - unsigned long flags; - unsigned int value; - local_irq_save(flags); - value = intc_set_field_from_handle(__raw_readb(ptr), data, h); - __raw_writeb(value, ptr); - (void)__raw_readb(ptr); /* Defeat write posting */ - local_irq_restore(flags); - return 0; -} - -static unsigned long modify_16(unsigned long addr, unsigned long h, - unsigned long data) -{ - void __iomem *ptr = (void __iomem *)addr; - unsigned long flags; - unsigned int value; - local_irq_save(flags); - value = intc_set_field_from_handle(__raw_readw(ptr), data, h); - __raw_writew(value, ptr); - (void)__raw_readw(ptr); /* Defeat write posting */ - local_irq_restore(flags); - return 0; -} - -static unsigned long modify_32(unsigned long addr, unsigned long h, - unsigned long data) -{ - void __iomem *ptr = (void __iomem *)addr; - unsigned long flags; - unsigned int value; - local_irq_save(flags); - value = intc_set_field_from_handle(__raw_readl(ptr), data, h); - __raw_writel(value, ptr); - (void)__raw_readl(ptr); /* Defeat write posting */ - local_irq_restore(flags); - return 0; -} - -static unsigned long intc_mode_field(unsigned long addr, - unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, - unsigned long), - unsigned int irq) -{ - return fn(addr, handle, ((1 << _INTC_WIDTH(handle)) - 1)); -} - -static unsigned long intc_mode_zero(unsigned long addr, - unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, - unsigned long), - unsigned int irq) -{ - return fn(addr, handle, 0); -} - -static unsigned long intc_mode_prio(unsigned long addr, - unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, - unsigned long), - unsigned int irq) -{ - return fn(addr, handle, intc_get_prio_level(irq)); -} - -unsigned long (*intc_reg_fns[])(unsigned long addr, - unsigned long h, - unsigned long data) = { - [REG_FN_TEST_BASE + 0] = test_8, - [REG_FN_TEST_BASE + 1] = test_16, - [REG_FN_TEST_BASE + 3] = test_32, - [REG_FN_WRITE_BASE + 0] = write_8, - [REG_FN_WRITE_BASE + 1] = write_16, - [REG_FN_WRITE_BASE + 3] = write_32, - [REG_FN_MODIFY_BASE + 0] = modify_8, - [REG_FN_MODIFY_BASE + 1] = modify_16, - [REG_FN_MODIFY_BASE + 3] = modify_32, -}; - -unsigned long (*intc_enable_fns[])(unsigned long addr, - unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, - unsigned long), - unsigned int irq) = { - [MODE_ENABLE_REG] = intc_mode_field, - [MODE_MASK_REG] = intc_mode_zero, - [MODE_DUAL_REG] = intc_mode_field, - [MODE_PRIO_REG] = intc_mode_prio, - [MODE_PCLR_REG] = intc_mode_prio, -}; - -unsigned long (*intc_disable_fns[])(unsigned long addr, - unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, - unsigned long), - unsigned int irq) = { - [MODE_ENABLE_REG] = intc_mode_zero, - [MODE_MASK_REG] = intc_mode_field, - [MODE_DUAL_REG] = intc_mode_field, - [MODE_PRIO_REG] = intc_mode_zero, - [MODE_PCLR_REG] = intc_mode_field, -}; - -unsigned long (*intc_enable_noprio_fns[])(unsigned long addr, - unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, - unsigned long), - unsigned int irq) = { - [MODE_ENABLE_REG] = intc_mode_field, - [MODE_MASK_REG] = intc_mode_zero, - [MODE_DUAL_REG] = intc_mode_field, - [MODE_PRIO_REG] = intc_mode_field, - [MODE_PCLR_REG] = intc_mode_field, -}; diff --git a/drivers/sh/intc/balancing.c b/drivers/sh/intc/balancing.c deleted file mode 100644 index bc780807ccb0fe..00000000000000 --- a/drivers/sh/intc/balancing.c +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Support for hardware-managed IRQ auto-distribution. - * - * Copyright (C) 2010 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include "internals.h" - -static unsigned long dist_handle[INTC_NR_IRQS]; - -void intc_balancing_enable(unsigned int irq) -{ - struct intc_desc_int *d = get_intc_desc(irq); - unsigned long handle = dist_handle[irq]; - unsigned long addr; - - if (irq_balancing_disabled(irq) || !handle) - return; - - addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); - intc_reg_fns[_INTC_FN(handle)](addr, handle, 1); -} - -void intc_balancing_disable(unsigned int irq) -{ - struct intc_desc_int *d = get_intc_desc(irq); - unsigned long handle = dist_handle[irq]; - unsigned long addr; - - if (irq_balancing_disabled(irq) || !handle) - return; - - addr = INTC_REG(d, _INTC_ADDR_D(handle), 0); - intc_reg_fns[_INTC_FN(handle)](addr, handle, 0); -} - -static unsigned int intc_dist_data(struct intc_desc *desc, - struct intc_desc_int *d, - intc_enum enum_id) -{ - struct intc_mask_reg *mr = desc->hw.mask_regs; - unsigned int i, j, fn, mode; - unsigned long reg_e, reg_d; - - for (i = 0; mr && enum_id && i < desc->hw.nr_mask_regs; i++) { - mr = desc->hw.mask_regs + i; - - /* - * Skip this entry if there's no auto-distribution - * register associated with it. - */ - if (!mr->dist_reg) - continue; - - for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { - if (mr->enum_ids[j] != enum_id) - continue; - - fn = REG_FN_MODIFY_BASE; - mode = MODE_ENABLE_REG; - reg_e = mr->dist_reg; - reg_d = mr->dist_reg; - - fn += (mr->reg_width >> 3) - 1; - return _INTC_MK(fn, mode, - intc_get_reg(d, reg_e), - intc_get_reg(d, reg_d), - 1, - (mr->reg_width - 1) - j); - } - } - - /* - * It's possible we've gotten here with no distribution options - * available for the IRQ in question, so we just skip over those. - */ - return 0; -} - -void intc_set_dist_handle(unsigned int irq, struct intc_desc *desc, - struct intc_desc_int *d, intc_enum id) -{ - unsigned long flags; - - /* - * Nothing to do for this IRQ. - */ - if (!desc->hw.mask_regs) - return; - - raw_spin_lock_irqsave(&intc_big_lock, flags); - dist_handle[irq] = intc_dist_data(desc, d, id); - raw_spin_unlock_irqrestore(&intc_big_lock, flags); -} diff --git a/drivers/sh/intc/chip.c b/drivers/sh/intc/chip.c deleted file mode 100644 index 828d81e02b37ab..00000000000000 --- a/drivers/sh/intc/chip.c +++ /dev/null @@ -1,211 +0,0 @@ -/* - * IRQ chip definitions for INTC IRQs. - * - * Copyright (C) 2007, 2008 Magnus Damm - * Copyright (C) 2009 - 2012 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include "internals.h" - -void _intc_enable(struct irq_data *data, unsigned long handle) -{ - unsigned int irq = data->irq; - struct intc_desc_int *d = get_intc_desc(irq); - unsigned long addr; - unsigned int cpu; - - for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { -#ifdef CONFIG_SMP - if (!cpumask_test_cpu(cpu, irq_data_get_affinity_mask(data))) - continue; -#endif - addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); - intc_enable_fns[_INTC_MODE(handle)](addr, handle, intc_reg_fns\ - [_INTC_FN(handle)], irq); - } - - intc_balancing_enable(irq); -} - -static void intc_enable(struct irq_data *data) -{ - _intc_enable(data, (unsigned long)irq_data_get_irq_chip_data(data)); -} - -static void intc_disable(struct irq_data *data) -{ - unsigned int irq = data->irq; - struct intc_desc_int *d = get_intc_desc(irq); - unsigned long handle = (unsigned long)irq_data_get_irq_chip_data(data); - unsigned long addr; - unsigned int cpu; - - intc_balancing_disable(irq); - - for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { -#ifdef CONFIG_SMP - if (!cpumask_test_cpu(cpu, irq_data_get_affinity_mask(data))) - continue; -#endif - addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); - intc_disable_fns[_INTC_MODE(handle)](addr, handle,intc_reg_fns\ - [_INTC_FN(handle)], irq); - } -} - -#ifdef CONFIG_SMP -/* - * This is held with the irq desc lock held, so we don't require any - * additional locking here at the intc desc level. The affinity mask is - * later tested in the enable/disable paths. - */ -static int intc_set_affinity(struct irq_data *data, - const struct cpumask *cpumask, - bool force) -{ - if (!cpumask_intersects(cpumask, cpu_online_mask)) - return -1; - - irq_data_update_affinity(data, cpumask); - - return IRQ_SET_MASK_OK_NOCOPY; -} -#endif - -static void intc_mask_ack(struct irq_data *data) -{ - unsigned int irq = data->irq; - struct intc_desc_int *d = get_intc_desc(irq); - unsigned long handle = intc_get_ack_handle(irq); - void __iomem *addr; - - intc_disable(data); - - /* read register and write zero only to the associated bit */ - if (handle) { - unsigned int value; - - addr = (void __iomem *)INTC_REG(d, _INTC_ADDR_D(handle), 0); - value = intc_set_field_from_handle(0, 1, handle); - - switch (_INTC_FN(handle)) { - case REG_FN_MODIFY_BASE + 0: /* 8bit */ - __raw_readb(addr); - __raw_writeb(0xff ^ value, addr); - break; - case REG_FN_MODIFY_BASE + 1: /* 16bit */ - __raw_readw(addr); - __raw_writew(0xffff ^ value, addr); - break; - case REG_FN_MODIFY_BASE + 3: /* 32bit */ - __raw_readl(addr); - __raw_writel(0xffffffff ^ value, addr); - break; - default: - BUG(); - break; - } - } -} - -static struct intc_handle_int *intc_find_irq(struct intc_handle_int *hp, - unsigned int nr_hp, - unsigned int irq) -{ - struct intc_handle_int key; - - key.irq = irq; - key.handle = 0; - - return bsearch(&key, hp, nr_hp, sizeof(*hp), intc_handle_int_cmp); -} - -int intc_set_priority(unsigned int irq, unsigned int prio) -{ - struct intc_desc_int *d = get_intc_desc(irq); - struct irq_data *data = irq_get_irq_data(irq); - struct intc_handle_int *ihp; - - if (!intc_get_prio_level(irq) || prio <= 1) - return -EINVAL; - - ihp = intc_find_irq(d->prio, d->nr_prio, irq); - if (ihp) { - if (prio >= (1 << _INTC_WIDTH(ihp->handle))) - return -EINVAL; - - intc_set_prio_level(irq, prio); - - /* - * only set secondary masking method directly - * primary masking method is using intc_prio_level[irq] - * priority level will be set during next enable() - */ - if (_INTC_FN(ihp->handle) != REG_FN_ERR) - _intc_enable(data, ihp->handle); - } - return 0; -} - -#define SENSE_VALID_FLAG 0x80 -#define VALID(x) (x | SENSE_VALID_FLAG) - -static unsigned char intc_irq_sense_table[IRQ_TYPE_SENSE_MASK + 1] = { - [IRQ_TYPE_EDGE_FALLING] = VALID(0), - [IRQ_TYPE_EDGE_RISING] = VALID(1), - [IRQ_TYPE_LEVEL_LOW] = VALID(2), - /* SH7706, SH7707 and SH7709 do not support high level triggered */ -#if !defined(CONFIG_CPU_SUBTYPE_SH7706) && \ - !defined(CONFIG_CPU_SUBTYPE_SH7707) && \ - !defined(CONFIG_CPU_SUBTYPE_SH7709) - [IRQ_TYPE_LEVEL_HIGH] = VALID(3), -#endif -#if defined(CONFIG_ARM) /* all recent SH-Mobile / R-Mobile ARM support this */ - [IRQ_TYPE_EDGE_BOTH] = VALID(4), -#endif -}; - -static int intc_set_type(struct irq_data *data, unsigned int type) -{ - unsigned int irq = data->irq; - struct intc_desc_int *d = get_intc_desc(irq); - unsigned char value = intc_irq_sense_table[type & IRQ_TYPE_SENSE_MASK]; - struct intc_handle_int *ihp; - unsigned long addr; - - if (!value) - return -EINVAL; - - value &= ~SENSE_VALID_FLAG; - - ihp = intc_find_irq(d->sense, d->nr_sense, irq); - if (ihp) { - /* PINT has 2-bit sense registers, should fail on EDGE_BOTH */ - if (value >= (1 << _INTC_WIDTH(ihp->handle))) - return -EINVAL; - - addr = INTC_REG(d, _INTC_ADDR_E(ihp->handle), 0); - intc_reg_fns[_INTC_FN(ihp->handle)](addr, ihp->handle, value); - } - - return 0; -} - -struct irq_chip intc_irq_chip = { - .irq_mask = intc_disable, - .irq_unmask = intc_enable, - .irq_mask_ack = intc_mask_ack, - .irq_enable = intc_enable, - .irq_disable = intc_disable, - .irq_set_type = intc_set_type, -#ifdef CONFIG_SMP - .irq_set_affinity = intc_set_affinity, -#endif - .flags = IRQCHIP_SKIP_SET_WAKE, -}; diff --git a/drivers/sh/intc/core.c b/drivers/sh/intc/core.c deleted file mode 100644 index ca4f4ca413f11d..00000000000000 --- a/drivers/sh/intc/core.c +++ /dev/null @@ -1,501 +0,0 @@ -/* - * Shared interrupt handling code for IPR and INTC2 types of IRQs. - * - * Copyright (C) 2007, 2008 Magnus Damm - * Copyright (C) 2009 - 2012 Paul Mundt - * - * Based on intc2.c and ipr.c - * - * Copyright (C) 1999 Niibe Yutaka & Takeshi Yaegashi - * Copyright (C) 2000 Kazumoto Kojima - * Copyright (C) 2001 David J. Mckay (david.mckay@st.com) - * Copyright (C) 2003 Takashi Kusuda - * Copyright (C) 2005, 2006 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "intc: " fmt - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include "internals.h" - -LIST_HEAD(intc_list); -DEFINE_RAW_SPINLOCK(intc_big_lock); -static unsigned int nr_intc_controllers; - -/* - * Default priority level - * - this needs to be at least 2 for 5-bit priorities on 7780 - */ -static unsigned int default_prio_level = 2; /* 2 - 16 */ -static unsigned int intc_prio_level[INTC_NR_IRQS]; /* for now */ - -unsigned int intc_get_dfl_prio_level(void) -{ - return default_prio_level; -} - -unsigned int intc_get_prio_level(unsigned int irq) -{ - return intc_prio_level[irq]; -} - -void intc_set_prio_level(unsigned int irq, unsigned int level) -{ - unsigned long flags; - - raw_spin_lock_irqsave(&intc_big_lock, flags); - intc_prio_level[irq] = level; - raw_spin_unlock_irqrestore(&intc_big_lock, flags); -} - -static void intc_redirect_irq(struct irq_desc *desc) -{ - generic_handle_irq((unsigned int)irq_desc_get_handler_data(desc)); -} - -static void __init intc_register_irq(struct intc_desc *desc, - struct intc_desc_int *d, - intc_enum enum_id, - unsigned int irq) -{ - struct intc_handle_int *hp; - struct irq_data *irq_data; - unsigned int data[2], primary; - unsigned long flags; - - raw_spin_lock_irqsave(&intc_big_lock, flags); - radix_tree_insert(&d->tree, enum_id, intc_irq_xlate_get(irq)); - raw_spin_unlock_irqrestore(&intc_big_lock, flags); - - /* - * Prefer single interrupt source bitmap over other combinations: - * - * 1. bitmap, single interrupt source - * 2. priority, single interrupt source - * 3. bitmap, multiple interrupt sources (groups) - * 4. priority, multiple interrupt sources (groups) - */ - data[0] = intc_get_mask_handle(desc, d, enum_id, 0); - data[1] = intc_get_prio_handle(desc, d, enum_id, 0); - - primary = 0; - if (!data[0] && data[1]) - primary = 1; - - if (!data[0] && !data[1]) - pr_warn("missing unique irq mask for irq %d (vect 0x%04x)\n", - irq, irq2evt(irq)); - - data[0] = data[0] ? data[0] : intc_get_mask_handle(desc, d, enum_id, 1); - data[1] = data[1] ? data[1] : intc_get_prio_handle(desc, d, enum_id, 1); - - if (!data[primary]) - primary ^= 1; - - BUG_ON(!data[primary]); /* must have primary masking method */ - - irq_data = irq_get_irq_data(irq); - - disable_irq_nosync(irq); - irq_set_chip_and_handler_name(irq, &d->chip, handle_level_irq, - "level"); - irq_set_chip_data(irq, (void *)data[primary]); - - /* - * set priority level - */ - intc_set_prio_level(irq, intc_get_dfl_prio_level()); - - /* enable secondary masking method if present */ - if (data[!primary]) - _intc_enable(irq_data, data[!primary]); - - /* add irq to d->prio list if priority is available */ - if (data[1]) { - hp = d->prio + d->nr_prio; - hp->irq = irq; - hp->handle = data[1]; - - if (primary) { - /* - * only secondary priority should access registers, so - * set _INTC_FN(h) = REG_FN_ERR for intc_set_priority() - */ - hp->handle &= ~_INTC_MK(0x0f, 0, 0, 0, 0, 0); - hp->handle |= _INTC_MK(REG_FN_ERR, 0, 0, 0, 0, 0); - } - d->nr_prio++; - } - - /* add irq to d->sense list if sense is available */ - data[0] = intc_get_sense_handle(desc, d, enum_id); - if (data[0]) { - (d->sense + d->nr_sense)->irq = irq; - (d->sense + d->nr_sense)->handle = data[0]; - d->nr_sense++; - } - - /* irq should be disabled by default */ - d->chip.irq_mask(irq_data); - - intc_set_ack_handle(irq, desc, d, enum_id); - intc_set_dist_handle(irq, desc, d, enum_id); - - activate_irq(irq); -} - -static unsigned int __init save_reg(struct intc_desc_int *d, - unsigned int cnt, - unsigned long value, - unsigned int smp) -{ - if (value) { - value = intc_phys_to_virt(d, value); - - d->reg[cnt] = value; -#ifdef CONFIG_SMP - d->smp[cnt] = smp; -#endif - return 1; - } - - return 0; -} - -static bool __init intc_map(struct irq_domain *domain, int irq) -{ - if (!irq_to_desc(irq) && irq_alloc_desc_at(irq, NUMA_NO_NODE) != irq) { - pr_err("uname to allocate IRQ %d\n", irq); - return false; - } - - if (irq_domain_associate(domain, irq, irq)) { - pr_err("domain association failure\n"); - return false; - } - - return true; -} - -int __init register_intc_controller(struct intc_desc *desc) -{ - unsigned int i, k, smp; - struct intc_hw_desc *hw = &desc->hw; - struct intc_desc_int *d; - struct resource *res; - - pr_info("Registered controller '%s' with %u IRQs\n", - desc->name, hw->nr_vectors); - - d = kzalloc(sizeof(*d), GFP_NOWAIT); - if (!d) - goto err0; - - INIT_LIST_HEAD(&d->list); - list_add_tail(&d->list, &intc_list); - - raw_spin_lock_init(&d->lock); - INIT_RADIX_TREE(&d->tree, GFP_ATOMIC); - - d->index = nr_intc_controllers; - - if (desc->num_resources) { - d->nr_windows = desc->num_resources; - d->window = kcalloc(d->nr_windows, sizeof(*d->window), - GFP_NOWAIT); - if (!d->window) - goto err1; - - for (k = 0; k < d->nr_windows; k++) { - res = desc->resource + k; - WARN_ON(resource_type(res) != IORESOURCE_MEM); - d->window[k].phys = res->start; - d->window[k].size = resource_size(res); - d->window[k].virt = ioremap(res->start, - resource_size(res)); - if (!d->window[k].virt) - goto err2; - } - } - - d->nr_reg = hw->mask_regs ? hw->nr_mask_regs * 2 : 0; -#ifdef CONFIG_INTC_BALANCING - if (d->nr_reg) - d->nr_reg += hw->nr_mask_regs; -#endif - d->nr_reg += hw->prio_regs ? hw->nr_prio_regs * 2 : 0; - d->nr_reg += hw->sense_regs ? hw->nr_sense_regs : 0; - d->nr_reg += hw->ack_regs ? hw->nr_ack_regs : 0; - d->nr_reg += hw->subgroups ? hw->nr_subgroups : 0; - - d->reg = kcalloc(d->nr_reg, sizeof(*d->reg), GFP_NOWAIT); - if (!d->reg) - goto err2; - -#ifdef CONFIG_SMP - d->smp = kcalloc(d->nr_reg, sizeof(*d->smp), GFP_NOWAIT); - if (!d->smp) - goto err3; -#endif - k = 0; - - if (hw->mask_regs) { - for (i = 0; i < hw->nr_mask_regs; i++) { - smp = IS_SMP(hw->mask_regs[i]); - k += save_reg(d, k, hw->mask_regs[i].set_reg, smp); - k += save_reg(d, k, hw->mask_regs[i].clr_reg, smp); -#ifdef CONFIG_INTC_BALANCING - k += save_reg(d, k, hw->mask_regs[i].dist_reg, 0); -#endif - } - } - - if (hw->prio_regs) { - d->prio = kcalloc(hw->nr_vectors, sizeof(*d->prio), - GFP_NOWAIT); - if (!d->prio) - goto err4; - - for (i = 0; i < hw->nr_prio_regs; i++) { - smp = IS_SMP(hw->prio_regs[i]); - k += save_reg(d, k, hw->prio_regs[i].set_reg, smp); - k += save_reg(d, k, hw->prio_regs[i].clr_reg, smp); - } - - sort(d->prio, hw->nr_prio_regs, sizeof(*d->prio), - intc_handle_int_cmp, NULL); - } - - if (hw->sense_regs) { - d->sense = kcalloc(hw->nr_vectors, sizeof(*d->sense), - GFP_NOWAIT); - if (!d->sense) - goto err5; - - for (i = 0; i < hw->nr_sense_regs; i++) - k += save_reg(d, k, hw->sense_regs[i].reg, 0); - - sort(d->sense, hw->nr_sense_regs, sizeof(*d->sense), - intc_handle_int_cmp, NULL); - } - - if (hw->subgroups) - for (i = 0; i < hw->nr_subgroups; i++) - if (hw->subgroups[i].reg) - k+= save_reg(d, k, hw->subgroups[i].reg, 0); - - memcpy(&d->chip, &intc_irq_chip, sizeof(struct irq_chip)); - d->chip.name = desc->name; - - if (hw->ack_regs) - for (i = 0; i < hw->nr_ack_regs; i++) - k += save_reg(d, k, hw->ack_regs[i].set_reg, 0); - else - d->chip.irq_mask_ack = d->chip.irq_disable; - - /* disable bits matching force_disable before registering irqs */ - if (desc->force_disable) - intc_enable_disable_enum(desc, d, desc->force_disable, 0); - - /* disable bits matching force_enable before registering irqs */ - if (desc->force_enable) - intc_enable_disable_enum(desc, d, desc->force_enable, 0); - - BUG_ON(k > 256); /* _INTC_ADDR_E() and _INTC_ADDR_D() are 8 bits */ - - intc_irq_domain_init(d, hw); - - /* register the vectors one by one */ - for (i = 0; i < hw->nr_vectors; i++) { - struct intc_vect *vect = hw->vectors + i; - unsigned int irq = evt2irq(vect->vect); - - if (!vect->enum_id) - continue; - - if (!intc_map(d->domain, irq)) - continue; - - intc_irq_xlate_set(irq, vect->enum_id, d); - intc_register_irq(desc, d, vect->enum_id, irq); - - for (k = i + 1; k < hw->nr_vectors; k++) { - struct intc_vect *vect2 = hw->vectors + k; - unsigned int irq2 = evt2irq(vect2->vect); - - if (vect->enum_id != vect2->enum_id) - continue; - - /* - * In the case of multi-evt handling and sparse - * IRQ support, each vector still needs to have - * its own backing irq_desc. - */ - if (!intc_map(d->domain, irq2)) - continue; - - vect2->enum_id = 0; - - /* redirect this interrupts to the first one */ - irq_set_chip(irq2, &dummy_irq_chip); - irq_set_chained_handler_and_data(irq2, - intc_redirect_irq, - (void *)irq); - } - } - - intc_subgroup_init(desc, d); - - /* enable bits matching force_enable after registering irqs */ - if (desc->force_enable) - intc_enable_disable_enum(desc, d, desc->force_enable, 1); - - d->skip_suspend = desc->skip_syscore_suspend; - - nr_intc_controllers++; - - return 0; -err5: - kfree(d->prio); -err4: -#ifdef CONFIG_SMP - kfree(d->smp); -err3: -#endif - kfree(d->reg); -err2: - for (k = 0; k < d->nr_windows; k++) - if (d->window[k].virt) - iounmap(d->window[k].virt); - - kfree(d->window); -err1: - kfree(d); -err0: - pr_err("unable to allocate INTC memory\n"); - - return -ENOMEM; -} - -static int intc_suspend(void) -{ - struct intc_desc_int *d; - - list_for_each_entry(d, &intc_list, list) { - int irq; - - if (d->skip_suspend) - continue; - - /* enable wakeup irqs belonging to this intc controller */ - for_each_active_irq(irq) { - struct irq_data *data; - struct irq_chip *chip; - - data = irq_get_irq_data(irq); - chip = irq_data_get_irq_chip(data); - if (chip != &d->chip) - continue; - if (irqd_is_wakeup_set(data)) - chip->irq_enable(data); - } - } - return 0; -} - -static void intc_resume(void) -{ - struct intc_desc_int *d; - - list_for_each_entry(d, &intc_list, list) { - int irq; - - if (d->skip_suspend) - continue; - - for_each_active_irq(irq) { - struct irq_data *data; - struct irq_chip *chip; - - data = irq_get_irq_data(irq); - chip = irq_data_get_irq_chip(data); - /* - * This will catch the redirect and VIRQ cases - * due to the dummy_irq_chip being inserted. - */ - if (chip != &d->chip) - continue; - if (irqd_irq_disabled(data)) - chip->irq_disable(data); - else - chip->irq_enable(data); - } - } -} - -struct syscore_ops intc_syscore_ops = { - .suspend = intc_suspend, - .resume = intc_resume, -}; - -struct bus_type intc_subsys = { - .name = "intc", - .dev_name = "intc", -}; - -static ssize_t -show_intc_name(struct device *dev, struct device_attribute *attr, char *buf) -{ - struct intc_desc_int *d; - - d = container_of(dev, struct intc_desc_int, dev); - - return sprintf(buf, "%s\n", d->chip.name); -} - -static DEVICE_ATTR(name, S_IRUGO, show_intc_name, NULL); - -static int __init register_intc_devs(void) -{ - struct intc_desc_int *d; - int error; - - register_syscore_ops(&intc_syscore_ops); - - error = subsys_system_register(&intc_subsys, NULL); - if (!error) { - list_for_each_entry(d, &intc_list, list) { - d->dev.id = d->index; - d->dev.bus = &intc_subsys; - error = device_register(&d->dev); - if (error == 0) - error = device_create_file(&d->dev, - &dev_attr_name); - if (error) - break; - } - } - - if (error) - pr_err("device registration error\n"); - - return error; -} -device_initcall(register_intc_devs); diff --git a/drivers/sh/intc/handle.c b/drivers/sh/intc/handle.c deleted file mode 100644 index 7863a44918a293..00000000000000 --- a/drivers/sh/intc/handle.c +++ /dev/null @@ -1,306 +0,0 @@ -/* - * Shared interrupt handling code for IPR and INTC2 types of IRQs. - * - * Copyright (C) 2007, 2008 Magnus Damm - * Copyright (C) 2009, 2010 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include "internals.h" - -static unsigned long ack_handle[INTC_NR_IRQS]; - -static intc_enum __init intc_grp_id(struct intc_desc *desc, - intc_enum enum_id) -{ - struct intc_group *g = desc->hw.groups; - unsigned int i, j; - - for (i = 0; g && enum_id && i < desc->hw.nr_groups; i++) { - g = desc->hw.groups + i; - - for (j = 0; g->enum_ids[j]; j++) { - if (g->enum_ids[j] != enum_id) - continue; - - return g->enum_id; - } - } - - return 0; -} - -static unsigned int __init _intc_mask_data(struct intc_desc *desc, - struct intc_desc_int *d, - intc_enum enum_id, - unsigned int *reg_idx, - unsigned int *fld_idx) -{ - struct intc_mask_reg *mr = desc->hw.mask_regs; - unsigned int fn, mode; - unsigned long reg_e, reg_d; - - while (mr && enum_id && *reg_idx < desc->hw.nr_mask_regs) { - mr = desc->hw.mask_regs + *reg_idx; - - for (; *fld_idx < ARRAY_SIZE(mr->enum_ids); (*fld_idx)++) { - if (mr->enum_ids[*fld_idx] != enum_id) - continue; - - if (mr->set_reg && mr->clr_reg) { - fn = REG_FN_WRITE_BASE; - mode = MODE_DUAL_REG; - reg_e = mr->clr_reg; - reg_d = mr->set_reg; - } else { - fn = REG_FN_MODIFY_BASE; - if (mr->set_reg) { - mode = MODE_ENABLE_REG; - reg_e = mr->set_reg; - reg_d = mr->set_reg; - } else { - mode = MODE_MASK_REG; - reg_e = mr->clr_reg; - reg_d = mr->clr_reg; - } - } - - fn += (mr->reg_width >> 3) - 1; - return _INTC_MK(fn, mode, - intc_get_reg(d, reg_e), - intc_get_reg(d, reg_d), - 1, - (mr->reg_width - 1) - *fld_idx); - } - - *fld_idx = 0; - (*reg_idx)++; - } - - return 0; -} - -unsigned int __init -intc_get_mask_handle(struct intc_desc *desc, struct intc_desc_int *d, - intc_enum enum_id, int do_grps) -{ - unsigned int i = 0; - unsigned int j = 0; - unsigned int ret; - - ret = _intc_mask_data(desc, d, enum_id, &i, &j); - if (ret) - return ret; - - if (do_grps) - return intc_get_mask_handle(desc, d, intc_grp_id(desc, enum_id), 0); - - return 0; -} - -static unsigned int __init _intc_prio_data(struct intc_desc *desc, - struct intc_desc_int *d, - intc_enum enum_id, - unsigned int *reg_idx, - unsigned int *fld_idx) -{ - struct intc_prio_reg *pr = desc->hw.prio_regs; - unsigned int fn, n, mode, bit; - unsigned long reg_e, reg_d; - - while (pr && enum_id && *reg_idx < desc->hw.nr_prio_regs) { - pr = desc->hw.prio_regs + *reg_idx; - - for (; *fld_idx < ARRAY_SIZE(pr->enum_ids); (*fld_idx)++) { - if (pr->enum_ids[*fld_idx] != enum_id) - continue; - - if (pr->set_reg && pr->clr_reg) { - fn = REG_FN_WRITE_BASE; - mode = MODE_PCLR_REG; - reg_e = pr->set_reg; - reg_d = pr->clr_reg; - } else { - fn = REG_FN_MODIFY_BASE; - mode = MODE_PRIO_REG; - if (!pr->set_reg) - BUG(); - reg_e = pr->set_reg; - reg_d = pr->set_reg; - } - - fn += (pr->reg_width >> 3) - 1; - n = *fld_idx + 1; - - BUG_ON(n * pr->field_width > pr->reg_width); - - bit = pr->reg_width - (n * pr->field_width); - - return _INTC_MK(fn, mode, - intc_get_reg(d, reg_e), - intc_get_reg(d, reg_d), - pr->field_width, bit); - } - - *fld_idx = 0; - (*reg_idx)++; - } - - return 0; -} - -unsigned int __init -intc_get_prio_handle(struct intc_desc *desc, struct intc_desc_int *d, - intc_enum enum_id, int do_grps) -{ - unsigned int i = 0; - unsigned int j = 0; - unsigned int ret; - - ret = _intc_prio_data(desc, d, enum_id, &i, &j); - if (ret) - return ret; - - if (do_grps) - return intc_get_prio_handle(desc, d, intc_grp_id(desc, enum_id), 0); - - return 0; -} - -static unsigned int intc_ack_data(struct intc_desc *desc, - struct intc_desc_int *d, intc_enum enum_id) -{ - struct intc_mask_reg *mr = desc->hw.ack_regs; - unsigned int i, j, fn, mode; - unsigned long reg_e, reg_d; - - for (i = 0; mr && enum_id && i < desc->hw.nr_ack_regs; i++) { - mr = desc->hw.ack_regs + i; - - for (j = 0; j < ARRAY_SIZE(mr->enum_ids); j++) { - if (mr->enum_ids[j] != enum_id) - continue; - - fn = REG_FN_MODIFY_BASE; - mode = MODE_ENABLE_REG; - reg_e = mr->set_reg; - reg_d = mr->set_reg; - - fn += (mr->reg_width >> 3) - 1; - return _INTC_MK(fn, mode, - intc_get_reg(d, reg_e), - intc_get_reg(d, reg_d), - 1, - (mr->reg_width - 1) - j); - } - } - - return 0; -} - -static void intc_enable_disable(struct intc_desc_int *d, - unsigned long handle, int do_enable) -{ - unsigned long addr; - unsigned int cpu; - unsigned long (*fn)(unsigned long, unsigned long, - unsigned long (*)(unsigned long, unsigned long, - unsigned long), - unsigned int); - - if (do_enable) { - for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_E(handle)); cpu++) { - addr = INTC_REG(d, _INTC_ADDR_E(handle), cpu); - fn = intc_enable_noprio_fns[_INTC_MODE(handle)]; - fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0); - } - } else { - for (cpu = 0; cpu < SMP_NR(d, _INTC_ADDR_D(handle)); cpu++) { - addr = INTC_REG(d, _INTC_ADDR_D(handle), cpu); - fn = intc_disable_fns[_INTC_MODE(handle)]; - fn(addr, handle, intc_reg_fns[_INTC_FN(handle)], 0); - } - } -} - -void __init intc_enable_disable_enum(struct intc_desc *desc, - struct intc_desc_int *d, - intc_enum enum_id, int enable) -{ - unsigned int i, j, data; - - /* go through and enable/disable all mask bits */ - i = j = 0; - do { - data = _intc_mask_data(desc, d, enum_id, &i, &j); - if (data) - intc_enable_disable(d, data, enable); - j++; - } while (data); - - /* go through and enable/disable all priority fields */ - i = j = 0; - do { - data = _intc_prio_data(desc, d, enum_id, &i, &j); - if (data) - intc_enable_disable(d, data, enable); - - j++; - } while (data); -} - -unsigned int __init -intc_get_sense_handle(struct intc_desc *desc, struct intc_desc_int *d, - intc_enum enum_id) -{ - struct intc_sense_reg *sr = desc->hw.sense_regs; - unsigned int i, j, fn, bit; - - for (i = 0; sr && enum_id && i < desc->hw.nr_sense_regs; i++) { - sr = desc->hw.sense_regs + i; - - for (j = 0; j < ARRAY_SIZE(sr->enum_ids); j++) { - if (sr->enum_ids[j] != enum_id) - continue; - - fn = REG_FN_MODIFY_BASE; - fn += (sr->reg_width >> 3) - 1; - - BUG_ON((j + 1) * sr->field_width > sr->reg_width); - - bit = sr->reg_width - ((j + 1) * sr->field_width); - - return _INTC_MK(fn, 0, intc_get_reg(d, sr->reg), - 0, sr->field_width, bit); - } - } - - return 0; -} - - -void intc_set_ack_handle(unsigned int irq, struct intc_desc *desc, - struct intc_desc_int *d, intc_enum id) -{ - unsigned long flags; - - /* - * Nothing to do for this IRQ. - */ - if (!desc->hw.ack_regs) - return; - - raw_spin_lock_irqsave(&intc_big_lock, flags); - ack_handle[irq] = intc_ack_data(desc, d, id); - raw_spin_unlock_irqrestore(&intc_big_lock, flags); -} - -unsigned long intc_get_ack_handle(unsigned int irq) -{ - return ack_handle[irq]; -} diff --git a/drivers/sh/intc/internals.h b/drivers/sh/intc/internals.h deleted file mode 100644 index fa73c173b56a60..00000000000000 --- a/drivers/sh/intc/internals.h +++ /dev/null @@ -1,191 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#include -#include -#include -#include -#include -#include -#include -#include - -#define _INTC_MK(fn, mode, addr_e, addr_d, width, shift) \ - ((shift) | ((width) << 5) | ((fn) << 9) | ((mode) << 13) | \ - ((addr_e) << 16) | ((addr_d << 24))) - -#define _INTC_SHIFT(h) (h & 0x1f) -#define _INTC_WIDTH(h) ((h >> 5) & 0xf) -#define _INTC_FN(h) ((h >> 9) & 0xf) -#define _INTC_MODE(h) ((h >> 13) & 0x7) -#define _INTC_ADDR_E(h) ((h >> 16) & 0xff) -#define _INTC_ADDR_D(h) ((h >> 24) & 0xff) - -#ifdef CONFIG_SMP -#define IS_SMP(x) (x.smp) -#define INTC_REG(d, x, c) (d->reg[(x)] + ((d->smp[(x)] & 0xff) * c)) -#define SMP_NR(d, x) ((d->smp[(x)] >> 8) ? (d->smp[(x)] >> 8) : 1) -#else -#define IS_SMP(x) 0 -#define INTC_REG(d, x, c) (d->reg[(x)]) -#define SMP_NR(d, x) 1 -#endif - -struct intc_handle_int { - unsigned int irq; - unsigned long handle; -}; - -struct intc_window { - phys_addr_t phys; - void __iomem *virt; - unsigned long size; -}; - -struct intc_map_entry { - intc_enum enum_id; - struct intc_desc_int *desc; -}; - -struct intc_subgroup_entry { - unsigned int pirq; - intc_enum enum_id; - unsigned long handle; -}; - -struct intc_desc_int { - struct list_head list; - struct device dev; - struct radix_tree_root tree; - raw_spinlock_t lock; - unsigned int index; - unsigned long *reg; -#ifdef CONFIG_SMP - unsigned long *smp; -#endif - unsigned int nr_reg; - struct intc_handle_int *prio; - unsigned int nr_prio; - struct intc_handle_int *sense; - unsigned int nr_sense; - struct intc_window *window; - unsigned int nr_windows; - struct irq_domain *domain; - struct irq_chip chip; - bool skip_suspend; -}; - - -enum { - REG_FN_ERR = 0, - REG_FN_TEST_BASE = 1, - REG_FN_WRITE_BASE = 5, - REG_FN_MODIFY_BASE = 9 -}; - -enum { MODE_ENABLE_REG = 0, /* Bit(s) set -> interrupt enabled */ - MODE_MASK_REG, /* Bit(s) set -> interrupt disabled */ - MODE_DUAL_REG, /* Two registers, set bit to enable / disable */ - MODE_PRIO_REG, /* Priority value written to enable interrupt */ - MODE_PCLR_REG, /* Above plus all bits set to disable interrupt */ -}; - -static inline struct intc_desc_int *get_intc_desc(unsigned int irq) -{ - struct irq_chip *chip = irq_get_chip(irq); - - return container_of(chip, struct intc_desc_int, chip); -} - -/* - * Grumble. - */ -static inline void activate_irq(int irq) -{ - irq_modify_status(irq, IRQ_NOREQUEST, IRQ_NOPROBE); -} - -static inline int intc_handle_int_cmp(const void *a, const void *b) -{ - const struct intc_handle_int *_a = a; - const struct intc_handle_int *_b = b; - - return _a->irq - _b->irq; -} - -/* access.c */ -extern unsigned long -(*intc_reg_fns[])(unsigned long addr, unsigned long h, unsigned long data); - -extern unsigned long -(*intc_enable_fns[])(unsigned long addr, unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, unsigned long), - unsigned int irq); -extern unsigned long -(*intc_disable_fns[])(unsigned long addr, unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, unsigned long), - unsigned int irq); -extern unsigned long -(*intc_enable_noprio_fns[])(unsigned long addr, unsigned long handle, - unsigned long (*fn)(unsigned long, - unsigned long, unsigned long), - unsigned int irq); - -unsigned long intc_phys_to_virt(struct intc_desc_int *d, unsigned long address); -unsigned int intc_get_reg(struct intc_desc_int *d, unsigned long address); -unsigned int intc_set_field_from_handle(unsigned int value, - unsigned int field_value, - unsigned int handle); -unsigned long intc_get_field_from_handle(unsigned int value, - unsigned int handle); - -/* balancing.c */ -#ifdef CONFIG_INTC_BALANCING -void intc_balancing_enable(unsigned int irq); -void intc_balancing_disable(unsigned int irq); -void intc_set_dist_handle(unsigned int irq, struct intc_desc *desc, - struct intc_desc_int *d, intc_enum id); -#else -static inline void intc_balancing_enable(unsigned int irq) { } -static inline void intc_balancing_disable(unsigned int irq) { } -static inline void -intc_set_dist_handle(unsigned int irq, struct intc_desc *desc, - struct intc_desc_int *d, intc_enum id) { } -#endif - -/* chip.c */ -extern struct irq_chip intc_irq_chip; -void _intc_enable(struct irq_data *data, unsigned long handle); - -/* core.c */ -extern struct list_head intc_list; -extern raw_spinlock_t intc_big_lock; -extern struct bus_type intc_subsys; - -unsigned int intc_get_dfl_prio_level(void); -unsigned int intc_get_prio_level(unsigned int irq); -void intc_set_prio_level(unsigned int irq, unsigned int level); - -/* handle.c */ -unsigned int intc_get_mask_handle(struct intc_desc *desc, - struct intc_desc_int *d, - intc_enum enum_id, int do_grps); -unsigned int intc_get_prio_handle(struct intc_desc *desc, - struct intc_desc_int *d, - intc_enum enum_id, int do_grps); -unsigned int intc_get_sense_handle(struct intc_desc *desc, - struct intc_desc_int *d, - intc_enum enum_id); -void intc_set_ack_handle(unsigned int irq, struct intc_desc *desc, - struct intc_desc_int *d, intc_enum id); -unsigned long intc_get_ack_handle(unsigned int irq); -void intc_enable_disable_enum(struct intc_desc *desc, struct intc_desc_int *d, - intc_enum enum_id, int enable); - -/* irqdomain.c */ -void intc_irq_domain_init(struct intc_desc_int *d, struct intc_hw_desc *hw); - -/* virq.c */ -void intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d); -void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d); -struct intc_map_entry *intc_irq_xlate_get(unsigned int irq); diff --git a/drivers/sh/intc/irqdomain.c b/drivers/sh/intc/irqdomain.c deleted file mode 100644 index 3968f1c3c5c308..00000000000000 --- a/drivers/sh/intc/irqdomain.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * IRQ domain support for SH INTC subsystem - * - * Copyright (C) 2012 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "intc: " fmt - -#include -#include -#include -#include "internals.h" - -/** - * intc_irq_domain_evt_xlate() - Generic xlate for vectored IRQs. - * - * This takes care of exception vector to hwirq translation through - * by way of evt2irq() translation. - * - * Note: For platforms that use a flat vector space without INTEVT this - * basically just mimics irq_domain_xlate_onecell() by way of a nopped - * out evt2irq() implementation. - */ -static int intc_evt_xlate(struct irq_domain *d, struct device_node *ctrlr, - const u32 *intspec, unsigned int intsize, - unsigned long *out_hwirq, unsigned int *out_type) -{ - if (WARN_ON(intsize < 1)) - return -EINVAL; - - *out_hwirq = evt2irq(intspec[0]); - *out_type = IRQ_TYPE_NONE; - - return 0; -} - -static const struct irq_domain_ops intc_evt_ops = { - .xlate = intc_evt_xlate, -}; - -void __init intc_irq_domain_init(struct intc_desc_int *d, - struct intc_hw_desc *hw) -{ - unsigned int irq_base, irq_end; - - /* - * Quick linear revmap check - */ - irq_base = evt2irq(hw->vectors[0].vect); - irq_end = evt2irq(hw->vectors[hw->nr_vectors - 1].vect); - - /* - * Linear domains have a hard-wired assertion that IRQs start at - * 0 in order to make some performance optimizations. Lamely - * restrict the linear case to these conditions here, taking the - * tree penalty for linear cases with non-zero hwirq bases. - */ - if (irq_base == 0 && irq_end == (irq_base + hw->nr_vectors - 1)) - d->domain = irq_domain_add_linear(NULL, hw->nr_vectors, - &intc_evt_ops, NULL); - else - d->domain = irq_domain_add_tree(NULL, &intc_evt_ops, NULL); - - BUG_ON(!d->domain); -} diff --git a/drivers/sh/intc/userimask.c b/drivers/sh/intc/userimask.c deleted file mode 100644 index f9f043a3d90a23..00000000000000 --- a/drivers/sh/intc/userimask.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Support for hardware-assisted userspace interrupt masking. - * - * Copyright (C) 2010 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "intc: " fmt - -#include -#include -#include -#include -#include -#include -#include "internals.h" - -static void __iomem *uimask; - -static ssize_t -show_intc_userimask(struct device *dev, - struct device_attribute *attr, char *buf) -{ - return sprintf(buf, "%d\n", (__raw_readl(uimask) >> 4) & 0xf); -} - -static ssize_t -store_intc_userimask(struct device *dev, - struct device_attribute *attr, - const char *buf, size_t count) -{ - unsigned long level; - - level = simple_strtoul(buf, NULL, 10); - - /* - * Minimal acceptable IRQ levels are in the 2 - 16 range, but - * these are chomped so as to not interfere with normal IRQs. - * - * Level 1 is a special case on some CPUs in that it's not - * directly settable, but given that USERIMASK cuts off below a - * certain level, we don't care about this limitation here. - * Level 0 on the other hand equates to user masking disabled. - * - * We use the default priority level as a cut off so that only - * special case opt-in IRQs can be mangled. - */ - if (level >= intc_get_dfl_prio_level()) - return -EINVAL; - - __raw_writel(0xa5 << 24 | level << 4, uimask); - - return count; -} - -static DEVICE_ATTR(userimask, S_IRUSR | S_IWUSR, - show_intc_userimask, store_intc_userimask); - - -static int __init userimask_sysdev_init(void) -{ - if (unlikely(!uimask)) - return -ENXIO; - - return device_create_file(intc_subsys.dev_root, &dev_attr_userimask); -} -late_initcall(userimask_sysdev_init); - -int register_intc_userimask(unsigned long addr) -{ - if (unlikely(uimask)) - return -EBUSY; - - uimask = ioremap(addr, SZ_4K); - if (unlikely(!uimask)) - return -ENOMEM; - - pr_info("userimask support registered for levels 0 -> %d\n", - intc_get_dfl_prio_level() - 1); - - return 0; -} diff --git a/drivers/sh/intc/virq-debugfs.c b/drivers/sh/intc/virq-debugfs.c deleted file mode 100644 index 939915a07d9997..00000000000000 --- a/drivers/sh/intc/virq-debugfs.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Support for virtual IRQ subgroups debugfs mapping. - * - * Copyright (C) 2010 Paul Mundt - * - * Modelled after arch/powerpc/kernel/irq.c. - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include "internals.h" - -static int intc_irq_xlate_show(struct seq_file *m, void *priv) -{ - int i; - - seq_printf(m, "%-5s %-7s %-15s\n", "irq", "enum", "chip name"); - - for (i = 1; i < nr_irqs; i++) { - struct intc_map_entry *entry = intc_irq_xlate_get(i); - struct intc_desc_int *desc = entry->desc; - - if (!desc) - continue; - - seq_printf(m, "%5d ", i); - seq_printf(m, "0x%05x ", entry->enum_id); - seq_printf(m, "%-15s\n", desc->chip.name); - } - - return 0; -} - -DEFINE_SHOW_ATTRIBUTE(intc_irq_xlate); - -static int __init intc_irq_xlate_init(void) -{ - /* - * XXX.. use arch_debugfs_dir here when all of the intc users are - * converted. - */ - if (debugfs_create_file("intc_irq_xlate", S_IRUGO, NULL, NULL, - &intc_irq_xlate_fops) == NULL) - return -ENOMEM; - - return 0; -} -fs_initcall(intc_irq_xlate_init); diff --git a/drivers/sh/intc/virq.c b/drivers/sh/intc/virq.c deleted file mode 100644 index a638c3048207c0..00000000000000 --- a/drivers/sh/intc/virq.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Support for virtual IRQ subgroups. - * - * Copyright (C) 2010 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#define pr_fmt(fmt) "intc: " fmt - -#include -#include -#include -#include -#include -#include -#include "internals.h" - -static struct intc_map_entry intc_irq_xlate[INTC_NR_IRQS]; - -struct intc_virq_list { - unsigned int irq; - struct intc_virq_list *next; -}; - -#define for_each_virq(entry, head) \ - for (entry = head; entry; entry = entry->next) - -/* - * Tags for the radix tree - */ -#define INTC_TAG_VIRQ_NEEDS_ALLOC 0 - -void intc_irq_xlate_set(unsigned int irq, intc_enum id, struct intc_desc_int *d) -{ - unsigned long flags; - - raw_spin_lock_irqsave(&intc_big_lock, flags); - intc_irq_xlate[irq].enum_id = id; - intc_irq_xlate[irq].desc = d; - raw_spin_unlock_irqrestore(&intc_big_lock, flags); -} - -struct intc_map_entry *intc_irq_xlate_get(unsigned int irq) -{ - return intc_irq_xlate + irq; -} - -int intc_irq_lookup(const char *chipname, intc_enum enum_id) -{ - struct intc_map_entry *ptr; - struct intc_desc_int *d; - int irq = -1; - - list_for_each_entry(d, &intc_list, list) { - int tagged; - - if (strcmp(d->chip.name, chipname) != 0) - continue; - - /* - * Catch early lookups for subgroup VIRQs that have not - * yet been allocated an IRQ. This already includes a - * fast-path out if the tree is untagged, so there is no - * need to explicitly test the root tree. - */ - tagged = radix_tree_tag_get(&d->tree, enum_id, - INTC_TAG_VIRQ_NEEDS_ALLOC); - if (unlikely(tagged)) - break; - - ptr = radix_tree_lookup(&d->tree, enum_id); - if (ptr) { - irq = ptr - intc_irq_xlate; - break; - } - } - - return irq; -} -EXPORT_SYMBOL_GPL(intc_irq_lookup); - -static int add_virq_to_pirq(unsigned int irq, unsigned int virq) -{ - struct intc_virq_list *entry; - struct intc_virq_list **last = NULL; - - /* scan for duplicates */ - for_each_virq(entry, irq_get_handler_data(irq)) { - if (entry->irq == virq) - return 0; - last = &entry->next; - } - - entry = kzalloc(sizeof(struct intc_virq_list), GFP_ATOMIC); - if (!entry) - return -ENOMEM; - - entry->irq = virq; - - if (last) - *last = entry; - else - irq_set_handler_data(irq, entry); - - return 0; -} - -static void intc_virq_handler(struct irq_desc *desc) -{ - unsigned int irq = irq_desc_get_irq(desc); - struct irq_data *data = irq_desc_get_irq_data(desc); - struct irq_chip *chip = irq_data_get_irq_chip(data); - struct intc_virq_list *entry, *vlist = irq_data_get_irq_handler_data(data); - struct intc_desc_int *d = get_intc_desc(irq); - - chip->irq_mask_ack(data); - - for_each_virq(entry, vlist) { - unsigned long addr, handle; - struct irq_desc *vdesc = irq_to_desc(entry->irq); - - if (vdesc) { - handle = (unsigned long)irq_desc_get_handler_data(vdesc); - addr = INTC_REG(d, _INTC_ADDR_E(handle), 0); - if (intc_reg_fns[_INTC_FN(handle)](addr, handle, 0)) - generic_handle_irq_desc(vdesc); - } - } - - chip->irq_unmask(data); -} - -static unsigned long __init intc_subgroup_data(struct intc_subgroup *subgroup, - struct intc_desc_int *d, - unsigned int index) -{ - unsigned int fn = REG_FN_TEST_BASE + (subgroup->reg_width >> 3) - 1; - - return _INTC_MK(fn, MODE_ENABLE_REG, intc_get_reg(d, subgroup->reg), - 0, 1, (subgroup->reg_width - 1) - index); -} - -static void __init intc_subgroup_init_one(struct intc_desc *desc, - struct intc_desc_int *d, - struct intc_subgroup *subgroup) -{ - struct intc_map_entry *mapped; - unsigned int pirq; - unsigned long flags; - int i; - - mapped = radix_tree_lookup(&d->tree, subgroup->parent_id); - if (!mapped) { - WARN_ON(1); - return; - } - - pirq = mapped - intc_irq_xlate; - - raw_spin_lock_irqsave(&d->lock, flags); - - for (i = 0; i < ARRAY_SIZE(subgroup->enum_ids); i++) { - struct intc_subgroup_entry *entry; - int err; - - if (!subgroup->enum_ids[i]) - continue; - - entry = kmalloc(sizeof(*entry), GFP_NOWAIT); - if (!entry) - break; - - entry->pirq = pirq; - entry->enum_id = subgroup->enum_ids[i]; - entry->handle = intc_subgroup_data(subgroup, d, i); - - err = radix_tree_insert(&d->tree, entry->enum_id, entry); - if (unlikely(err < 0)) - break; - - radix_tree_tag_set(&d->tree, entry->enum_id, - INTC_TAG_VIRQ_NEEDS_ALLOC); - } - - raw_spin_unlock_irqrestore(&d->lock, flags); -} - -void __init intc_subgroup_init(struct intc_desc *desc, struct intc_desc_int *d) -{ - int i; - - if (!desc->hw.subgroups) - return; - - for (i = 0; i < desc->hw.nr_subgroups; i++) - intc_subgroup_init_one(desc, d, desc->hw.subgroups + i); -} - -static void __init intc_subgroup_map(struct intc_desc_int *d) -{ - struct intc_subgroup_entry *entries[32]; - unsigned long flags; - unsigned int nr_found; - int i; - - raw_spin_lock_irqsave(&d->lock, flags); - -restart: - nr_found = radix_tree_gang_lookup_tag_slot(&d->tree, - (void ***)entries, 0, ARRAY_SIZE(entries), - INTC_TAG_VIRQ_NEEDS_ALLOC); - - for (i = 0; i < nr_found; i++) { - struct intc_subgroup_entry *entry; - int irq; - - entry = radix_tree_deref_slot((void **)entries[i]); - if (unlikely(!entry)) - continue; - if (radix_tree_deref_retry(entry)) - goto restart; - - irq = irq_alloc_desc(numa_node_id()); - if (unlikely(irq < 0)) { - pr_err("no more free IRQs, bailing..\n"); - break; - } - - activate_irq(irq); - - pr_info("Setting up a chained VIRQ from %d -> %d\n", - irq, entry->pirq); - - intc_irq_xlate_set(irq, entry->enum_id, d); - - irq_set_chip_and_handler_name(irq, irq_get_chip(entry->pirq), - handle_simple_irq, "virq"); - irq_set_chip_data(irq, irq_get_chip_data(entry->pirq)); - - irq_set_handler_data(irq, (void *)entry->handle); - - /* - * Set the virtual IRQ as non-threadable. - */ - irq_set_nothread(irq); - - /* Set handler data before installing the handler */ - add_virq_to_pirq(entry->pirq, irq); - irq_set_chained_handler(entry->pirq, intc_virq_handler); - - radix_tree_tag_clear(&d->tree, entry->enum_id, - INTC_TAG_VIRQ_NEEDS_ALLOC); - radix_tree_replace_slot(&d->tree, (void **)entries[i], - &intc_irq_xlate[irq]); - } - - raw_spin_unlock_irqrestore(&d->lock, flags); -} - -void __init intc_finalize(void) -{ - struct intc_desc_int *d; - - list_for_each_entry(d, &intc_list, list) - if (radix_tree_tagged(&d->tree, INTC_TAG_VIRQ_NEEDS_ALLOC)) - intc_subgroup_map(d); -} diff --git a/drivers/sh/maple/Makefile b/drivers/sh/maple/Makefile deleted file mode 100644 index c3a80910c212ce..00000000000000 --- a/drivers/sh/maple/Makefile +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# Makefile for Maple Bus - -obj-$(CONFIG_MAPLE) := maple.o diff --git a/drivers/sh/maple/maple.c b/drivers/sh/maple/maple.c deleted file mode 100644 index e24e220e56eea1..00000000000000 --- a/drivers/sh/maple/maple.c +++ /dev/null @@ -1,895 +0,0 @@ -/* - * Core maple bus functionality - * - * Copyright (C) 2007 - 2009 Adrian McMenamin - * Copyright (C) 2001 - 2008 Paul Mundt - * Copyright (C) 2000 - 2001 YAEGASHI Takeshi - * Copyright (C) 2001 M. R. Brown - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -MODULE_AUTHOR("Adrian McMenamin "); -MODULE_DESCRIPTION("Maple bus driver for Dreamcast"); -MODULE_LICENSE("GPL v2"); - -static void maple_dma_handler(struct work_struct *work); -static void maple_vblank_handler(struct work_struct *work); - -static DECLARE_WORK(maple_dma_process, maple_dma_handler); -static DECLARE_WORK(maple_vblank_process, maple_vblank_handler); - -static LIST_HEAD(maple_waitq); -static LIST_HEAD(maple_sentq); - -/* mutex to protect queue of waiting packets */ -static DEFINE_MUTEX(maple_wlist_lock); - -static struct maple_driver maple_unsupported_device; -static struct device maple_bus; -static int subdevice_map[MAPLE_PORTS]; -static unsigned long *maple_sendbuf, *maple_sendptr, *maple_lastptr; -static unsigned long maple_pnp_time; -static int started, scanning, fullscan; -static struct kmem_cache *maple_queue_cache; - -struct maple_device_specify { - int port; - int unit; -}; - -static bool checked[MAPLE_PORTS]; -static bool empty[MAPLE_PORTS]; -static struct maple_device *baseunits[MAPLE_PORTS]; - -/** - * maple_driver_register - register a maple driver - * @drv: maple driver to be registered. - * - * Registers the passed in @drv, while updating the bus type. - * Devices with matching function IDs will be automatically probed. - */ -int maple_driver_register(struct maple_driver *drv) -{ - if (!drv) - return -EINVAL; - - drv->drv.bus = &maple_bus_type; - - return driver_register(&drv->drv); -} -EXPORT_SYMBOL_GPL(maple_driver_register); - -/** - * maple_driver_unregister - unregister a maple driver. - * @drv: maple driver to unregister. - * - * Cleans up after maple_driver_register(). To be invoked in the exit - * path of any module drivers. - */ -void maple_driver_unregister(struct maple_driver *drv) -{ - driver_unregister(&drv->drv); -} -EXPORT_SYMBOL_GPL(maple_driver_unregister); - -/* set hardware registers to enable next round of dma */ -static void maple_dma_reset(void) -{ - __raw_writel(MAPLE_MAGIC, MAPLE_RESET); - /* set trig type to 0 for software trigger, 1 for hardware (VBLANK) */ - __raw_writel(1, MAPLE_TRIGTYPE); - /* - * Maple system register - * bits 31 - 16 timeout in units of 20nsec - * bit 12 hard trigger - set 0 to keep responding to VBLANK - * bits 9 - 8 set 00 for 2 Mbps, 01 for 1 Mbps - * bits 3 - 0 delay (in 1.3ms) between VBLANK and start of DMA - * max delay is 11 - */ - __raw_writel(MAPLE_2MBPS | MAPLE_TIMEOUT(0xFFFF), MAPLE_SPEED); - __raw_writel(virt_to_phys(maple_sendbuf), MAPLE_DMAADDR); - __raw_writel(1, MAPLE_ENABLE); -} - -/** - * maple_getcond_callback - setup handling MAPLE_COMMAND_GETCOND - * @dev: device responding - * @callback: handler callback - * @interval: interval in jiffies between callbacks - * @function: the function code for the device - */ -void maple_getcond_callback(struct maple_device *dev, - void (*callback) (struct mapleq *mq), - unsigned long interval, unsigned long function) -{ - dev->callback = callback; - dev->interval = interval; - dev->function = cpu_to_be32(function); - dev->when = jiffies; -} -EXPORT_SYMBOL_GPL(maple_getcond_callback); - -static int maple_dma_done(void) -{ - return (__raw_readl(MAPLE_STATE) & 1) == 0; -} - -static void maple_release_device(struct device *dev) -{ - struct maple_device *mdev; - struct mapleq *mq; - - mdev = to_maple_dev(dev); - mq = mdev->mq; - kmem_cache_free(maple_queue_cache, mq->recvbuf); - kfree(mq); - kfree(mdev); -} - -/** - * maple_add_packet - add a single instruction to the maple bus queue - * @mdev: maple device - * @function: function on device being queried - * @command: maple command to add - * @length: length of command string (in 32 bit words) - * @data: remainder of command string - */ -int maple_add_packet(struct maple_device *mdev, u32 function, u32 command, - size_t length, void *data) -{ - int ret = 0; - void *sendbuf = NULL; - - if (length) { - sendbuf = kcalloc(length, 4, GFP_KERNEL); - if (!sendbuf) { - ret = -ENOMEM; - goto out; - } - ((__be32 *)sendbuf)[0] = cpu_to_be32(function); - } - - mdev->mq->command = command; - mdev->mq->length = length; - if (length > 1) - memcpy(sendbuf + 4, data, (length - 1) * 4); - mdev->mq->sendbuf = sendbuf; - - mutex_lock(&maple_wlist_lock); - list_add_tail(&mdev->mq->list, &maple_waitq); - mutex_unlock(&maple_wlist_lock); -out: - return ret; -} -EXPORT_SYMBOL_GPL(maple_add_packet); - -static struct mapleq *maple_allocq(struct maple_device *mdev) -{ - struct mapleq *mq; - - mq = kzalloc(sizeof(*mq), GFP_KERNEL); - if (!mq) - goto failed_nomem; - - INIT_LIST_HEAD(&mq->list); - mq->dev = mdev; - mq->recvbuf = kmem_cache_zalloc(maple_queue_cache, GFP_KERNEL); - if (!mq->recvbuf) - goto failed_p2; - mq->recvbuf->buf = &((mq->recvbuf->bufx)[0]); - - return mq; - -failed_p2: - kfree(mq); -failed_nomem: - dev_err(&mdev->dev, "could not allocate memory for device (%d, %d)\n", - mdev->port, mdev->unit); - return NULL; -} - -static struct maple_device *maple_alloc_dev(int port, int unit) -{ - struct maple_device *mdev; - - /* zero this out to avoid kobj subsystem - * thinking it has already been registered */ - - mdev = kzalloc(sizeof(*mdev), GFP_KERNEL); - if (!mdev) - return NULL; - - mdev->port = port; - mdev->unit = unit; - - mdev->mq = maple_allocq(mdev); - - if (!mdev->mq) { - kfree(mdev); - return NULL; - } - mdev->dev.bus = &maple_bus_type; - mdev->dev.parent = &maple_bus; - init_waitqueue_head(&mdev->maple_wait); - return mdev; -} - -static void maple_free_dev(struct maple_device *mdev) -{ - kmem_cache_free(maple_queue_cache, mdev->mq->recvbuf); - kfree(mdev->mq); - kfree(mdev); -} - -/* process the command queue into a maple command block - * terminating command has bit 32 of first long set to 0 - */ -static void maple_build_block(struct mapleq *mq) -{ - int port, unit, from, to, len; - unsigned long *lsendbuf = mq->sendbuf; - - port = mq->dev->port & 3; - unit = mq->dev->unit; - len = mq->length; - from = port << 6; - to = (port << 6) | (unit > 0 ? (1 << (unit - 1)) & 0x1f : 0x20); - - *maple_lastptr &= 0x7fffffff; - maple_lastptr = maple_sendptr; - - *maple_sendptr++ = (port << 16) | len | 0x80000000; - *maple_sendptr++ = virt_to_phys(mq->recvbuf->buf); - *maple_sendptr++ = - mq->command | (to << 8) | (from << 16) | (len << 24); - while (len-- > 0) - *maple_sendptr++ = *lsendbuf++; -} - -/* build up command queue */ -static void maple_send(void) -{ - int i, maple_packets = 0; - struct mapleq *mq, *nmq; - - if (!maple_dma_done()) - return; - - /* disable DMA */ - __raw_writel(0, MAPLE_ENABLE); - - if (!list_empty(&maple_sentq)) - goto finish; - - mutex_lock(&maple_wlist_lock); - if (list_empty(&maple_waitq)) { - mutex_unlock(&maple_wlist_lock); - goto finish; - } - - maple_lastptr = maple_sendbuf; - maple_sendptr = maple_sendbuf; - - list_for_each_entry_safe(mq, nmq, &maple_waitq, list) { - maple_build_block(mq); - list_del_init(&mq->list); - list_add_tail(&mq->list, &maple_sentq); - if (maple_packets++ > MAPLE_MAXPACKETS) - break; - } - mutex_unlock(&maple_wlist_lock); - if (maple_packets > 0) { - for (i = 0; i < (1 << MAPLE_DMA_PAGES); i++) - __flush_purge_region(maple_sendbuf + i * PAGE_SIZE, - PAGE_SIZE); - } - -finish: - maple_dma_reset(); -} - -/* check if there is a driver registered likely to match this device */ -static int maple_check_matching_driver(struct device_driver *driver, - void *devptr) -{ - struct maple_driver *maple_drv; - struct maple_device *mdev; - - mdev = devptr; - maple_drv = to_maple_driver(driver); - if (mdev->devinfo.function & cpu_to_be32(maple_drv->function)) - return 1; - return 0; -} - -static void maple_detach_driver(struct maple_device *mdev) -{ - device_unregister(&mdev->dev); -} - -/* process initial MAPLE_COMMAND_DEVINFO for each device or port */ -static void maple_attach_driver(struct maple_device *mdev) -{ - char *p, *recvbuf; - unsigned long function; - int matched, error; - - recvbuf = mdev->mq->recvbuf->buf; - /* copy the data as individual elements in - * case of memory optimisation */ - memcpy(&mdev->devinfo.function, recvbuf + 4, 4); - memcpy(&mdev->devinfo.function_data[0], recvbuf + 8, 12); - memcpy(&mdev->devinfo.area_code, recvbuf + 20, 1); - memcpy(&mdev->devinfo.connector_direction, recvbuf + 21, 1); - memcpy(&mdev->devinfo.product_name[0], recvbuf + 22, 30); - memcpy(&mdev->devinfo.standby_power, recvbuf + 112, 2); - memcpy(&mdev->devinfo.max_power, recvbuf + 114, 2); - memcpy(mdev->product_name, mdev->devinfo.product_name, 30); - mdev->product_name[30] = '\0'; - memcpy(mdev->product_licence, mdev->devinfo.product_licence, 60); - mdev->product_licence[60] = '\0'; - - for (p = mdev->product_name + 29; mdev->product_name <= p; p--) - if (*p == ' ') - *p = '\0'; - else - break; - for (p = mdev->product_licence + 59; mdev->product_licence <= p; p--) - if (*p == ' ') - *p = '\0'; - else - break; - - function = be32_to_cpu(mdev->devinfo.function); - - dev_info(&mdev->dev, "detected %s: function 0x%lX: at (%d, %d)\n", - mdev->product_name, function, mdev->port, mdev->unit); - - if (function > 0x200) { - /* Do this silently - as not a real device */ - function = 0; - mdev->driver = &maple_unsupported_device; - dev_set_name(&mdev->dev, "%d:0.port", mdev->port); - } else { - matched = - bus_for_each_drv(&maple_bus_type, NULL, mdev, - maple_check_matching_driver); - - if (matched == 0) { - /* Driver does not exist yet */ - dev_info(&mdev->dev, "no driver found\n"); - mdev->driver = &maple_unsupported_device; - } - dev_set_name(&mdev->dev, "%d:0%d.%lX", mdev->port, - mdev->unit, function); - } - - mdev->function = function; - mdev->dev.release = &maple_release_device; - - atomic_set(&mdev->busy, 0); - error = device_register(&mdev->dev); - if (error) { - dev_warn(&mdev->dev, "could not register device at" - " (%d, %d), with error 0x%X\n", mdev->unit, - mdev->port, error); - maple_free_dev(mdev); - mdev = NULL; - return; - } -} - -/* - * if device has been registered for the given - * port and unit then return 1 - allows identification - * of which devices need to be attached or detached - */ -static int check_maple_device(struct device *device, void *portptr) -{ - struct maple_device_specify *ds; - struct maple_device *mdev; - - ds = portptr; - mdev = to_maple_dev(device); - if (mdev->port == ds->port && mdev->unit == ds->unit) - return 1; - return 0; -} - -static int setup_maple_commands(struct device *device, void *ignored) -{ - int add; - struct maple_device *mdev = to_maple_dev(device); - if (mdev->interval > 0 && atomic_read(&mdev->busy) == 0 && - time_after(jiffies, mdev->when)) { - /* bounce if we cannot add */ - add = maple_add_packet(mdev, - be32_to_cpu(mdev->devinfo.function), - MAPLE_COMMAND_GETCOND, 1, NULL); - if (!add) - mdev->when = jiffies + mdev->interval; - } else { - if (time_after(jiffies, maple_pnp_time)) - /* Ensure we don't have block reads and devinfo - * calls interfering with one another - so flag the - * device as busy */ - if (atomic_read(&mdev->busy) == 0) { - atomic_set(&mdev->busy, 1); - maple_add_packet(mdev, 0, - MAPLE_COMMAND_DEVINFO, 0, NULL); - } - } - return 0; -} - -/* VBLANK bottom half - implemented via workqueue */ -static void maple_vblank_handler(struct work_struct *work) -{ - int x, locking; - struct maple_device *mdev; - - if (!maple_dma_done()) - return; - - __raw_writel(0, MAPLE_ENABLE); - - if (!list_empty(&maple_sentq)) - goto finish; - - /* - * Set up essential commands - to fetch data and - * check devices are still present - */ - bus_for_each_dev(&maple_bus_type, NULL, NULL, - setup_maple_commands); - - if (time_after(jiffies, maple_pnp_time)) { - /* - * Scan the empty ports - bus is flakey and may have - * mis-reported emptyness - */ - for (x = 0; x < MAPLE_PORTS; x++) { - if (checked[x] && empty[x]) { - mdev = baseunits[x]; - if (!mdev) - break; - atomic_set(&mdev->busy, 1); - locking = maple_add_packet(mdev, 0, - MAPLE_COMMAND_DEVINFO, 0, NULL); - if (!locking) - break; - } - } - - maple_pnp_time = jiffies + MAPLE_PNP_INTERVAL; - } - -finish: - maple_send(); -} - -/* handle devices added via hotplugs - placing them on queue for DEVINFO */ -static void maple_map_subunits(struct maple_device *mdev, int submask) -{ - int retval, k, devcheck; - struct maple_device *mdev_add; - struct maple_device_specify ds; - - ds.port = mdev->port; - for (k = 0; k < 5; k++) { - ds.unit = k + 1; - retval = - bus_for_each_dev(&maple_bus_type, NULL, &ds, - check_maple_device); - if (retval) { - submask = submask >> 1; - continue; - } - devcheck = submask & 0x01; - if (devcheck) { - mdev_add = maple_alloc_dev(mdev->port, k + 1); - if (!mdev_add) - return; - atomic_set(&mdev_add->busy, 1); - maple_add_packet(mdev_add, 0, MAPLE_COMMAND_DEVINFO, - 0, NULL); - /* mark that we are checking sub devices */ - scanning = 1; - } - submask = submask >> 1; - } -} - -/* mark a device as removed */ -static void maple_clean_submap(struct maple_device *mdev) -{ - int killbit; - - killbit = (mdev->unit > 0 ? (1 << (mdev->unit - 1)) & 0x1f : 0x20); - killbit = ~killbit; - killbit &= 0xFF; - subdevice_map[mdev->port] = subdevice_map[mdev->port] & killbit; -} - -/* handle empty port or hotplug removal */ -static void maple_response_none(struct maple_device *mdev) -{ - maple_clean_submap(mdev); - - if (likely(mdev->unit != 0)) { - /* - * Block devices play up - * and give the impression they have - * been removed even when still in place or - * trip the mtd layer when they have - * really gone - this code traps that eventuality - * and ensures we aren't overloaded with useless - * error messages - */ - if (mdev->can_unload) { - if (!mdev->can_unload(mdev)) { - atomic_set(&mdev->busy, 2); - wake_up(&mdev->maple_wait); - return; - } - } - - dev_info(&mdev->dev, "detaching device at (%d, %d)\n", - mdev->port, mdev->unit); - maple_detach_driver(mdev); - return; - } else { - if (!started || !fullscan) { - if (checked[mdev->port] == false) { - checked[mdev->port] = true; - empty[mdev->port] = true; - dev_info(&mdev->dev, "no devices" - " to port %d\n", mdev->port); - } - return; - } - } - /* Some hardware devices generate false detach messages on unit 0 */ - atomic_set(&mdev->busy, 0); -} - -/* preprocess hotplugs or scans */ -static void maple_response_devinfo(struct maple_device *mdev, - char *recvbuf) -{ - char submask; - if (!started || (scanning == 2) || !fullscan) { - if ((mdev->unit == 0) && (checked[mdev->port] == false)) { - checked[mdev->port] = true; - maple_attach_driver(mdev); - } else { - if (mdev->unit != 0) - maple_attach_driver(mdev); - if (mdev->unit == 0) { - empty[mdev->port] = false; - maple_attach_driver(mdev); - } - } - } - if (mdev->unit == 0) { - submask = recvbuf[2] & 0x1F; - if (submask ^ subdevice_map[mdev->port]) { - maple_map_subunits(mdev, submask); - subdevice_map[mdev->port] = submask; - } - } -} - -static void maple_response_fileerr(struct maple_device *mdev, void *recvbuf) -{ - if (mdev->fileerr_handler) { - mdev->fileerr_handler(mdev, recvbuf); - return; - } else - dev_warn(&mdev->dev, "device at (%d, %d) reports" - "file error 0x%X\n", mdev->port, mdev->unit, - ((int *)recvbuf)[1]); -} - -static void maple_port_rescan(void) -{ - int i; - struct maple_device *mdev; - - fullscan = 1; - for (i = 0; i < MAPLE_PORTS; i++) { - if (checked[i] == false) { - fullscan = 0; - mdev = baseunits[i]; - maple_add_packet(mdev, 0, MAPLE_COMMAND_DEVINFO, - 0, NULL); - } - } -} - -/* maple dma end bottom half - implemented via workqueue */ -static void maple_dma_handler(struct work_struct *work) -{ - struct mapleq *mq, *nmq; - struct maple_device *mdev; - char *recvbuf; - enum maple_code code; - - if (!maple_dma_done()) - return; - __raw_writel(0, MAPLE_ENABLE); - if (!list_empty(&maple_sentq)) { - list_for_each_entry_safe(mq, nmq, &maple_sentq, list) { - mdev = mq->dev; - recvbuf = mq->recvbuf->buf; - __flush_invalidate_region(sh_cacheop_vaddr(recvbuf), - 0x400); - code = recvbuf[0]; - kfree(mq->sendbuf); - list_del_init(&mq->list); - switch (code) { - case MAPLE_RESPONSE_NONE: - maple_response_none(mdev); - break; - - case MAPLE_RESPONSE_DEVINFO: - maple_response_devinfo(mdev, recvbuf); - atomic_set(&mdev->busy, 0); - break; - - case MAPLE_RESPONSE_DATATRF: - if (mdev->callback) - mdev->callback(mq); - atomic_set(&mdev->busy, 0); - wake_up(&mdev->maple_wait); - break; - - case MAPLE_RESPONSE_FILEERR: - maple_response_fileerr(mdev, recvbuf); - atomic_set(&mdev->busy, 0); - wake_up(&mdev->maple_wait); - break; - - case MAPLE_RESPONSE_AGAIN: - case MAPLE_RESPONSE_BADCMD: - case MAPLE_RESPONSE_BADFUNC: - dev_warn(&mdev->dev, "non-fatal error" - " 0x%X at (%d, %d)\n", code, - mdev->port, mdev->unit); - atomic_set(&mdev->busy, 0); - break; - - case MAPLE_RESPONSE_ALLINFO: - dev_notice(&mdev->dev, "extended" - " device information request for (%d, %d)" - " but call is not supported\n", mdev->port, - mdev->unit); - atomic_set(&mdev->busy, 0); - break; - - case MAPLE_RESPONSE_OK: - atomic_set(&mdev->busy, 0); - wake_up(&mdev->maple_wait); - break; - - default: - break; - } - } - /* if scanning is 1 then we have subdevices to check */ - if (scanning == 1) { - maple_send(); - scanning = 2; - } else - scanning = 0; - /*check if we have actually tested all ports yet */ - if (!fullscan) - maple_port_rescan(); - /* mark that we have been through the first scan */ - started = 1; - } - maple_send(); -} - -static irqreturn_t maple_dma_interrupt(int irq, void *dev_id) -{ - /* Load everything into the bottom half */ - schedule_work(&maple_dma_process); - return IRQ_HANDLED; -} - -static irqreturn_t maple_vblank_interrupt(int irq, void *dev_id) -{ - schedule_work(&maple_vblank_process); - return IRQ_HANDLED; -} - -static int maple_set_dma_interrupt_handler(void) -{ - return request_irq(HW_EVENT_MAPLE_DMA, maple_dma_interrupt, - IRQF_SHARED, "maple bus DMA", &maple_unsupported_device); -} - -static int maple_set_vblank_interrupt_handler(void) -{ - return request_irq(HW_EVENT_VSYNC, maple_vblank_interrupt, - IRQF_SHARED, "maple bus VBLANK", &maple_unsupported_device); -} - -static int maple_get_dma_buffer(void) -{ - maple_sendbuf = - (void *) __get_free_pages(GFP_KERNEL | __GFP_ZERO, - MAPLE_DMA_PAGES); - if (!maple_sendbuf) - return -ENOMEM; - return 0; -} - -static int maple_match_bus_driver(struct device *devptr, - struct device_driver *drvptr) -{ - struct maple_driver *maple_drv = to_maple_driver(drvptr); - struct maple_device *maple_dev = to_maple_dev(devptr); - - /* Trap empty port case */ - if (maple_dev->devinfo.function == 0xFFFFFFFF) - return 0; - else if (maple_dev->devinfo.function & - cpu_to_be32(maple_drv->function)) - return 1; - return 0; -} - -static int maple_bus_uevent(struct device *dev, - struct kobj_uevent_env *env) -{ - return 0; -} - -static void maple_bus_release(struct device *dev) -{ -} - -static struct maple_driver maple_unsupported_device = { - .drv = { - .name = "maple_unsupported_device", - .bus = &maple_bus_type, - }, -}; -/* - * maple_bus_type - core maple bus structure - */ -struct bus_type maple_bus_type = { - .name = "maple", - .match = maple_match_bus_driver, - .uevent = maple_bus_uevent, -}; -EXPORT_SYMBOL_GPL(maple_bus_type); - -static struct device maple_bus = { - .init_name = "maple", - .release = maple_bus_release, -}; - -static int __init maple_bus_init(void) -{ - int retval, i; - struct maple_device *mdev[MAPLE_PORTS]; - - __raw_writel(0, MAPLE_ENABLE); - - retval = device_register(&maple_bus); - if (retval) - goto cleanup; - - retval = bus_register(&maple_bus_type); - if (retval) - goto cleanup_device; - - retval = driver_register(&maple_unsupported_device.drv); - if (retval) - goto cleanup_bus; - - /* allocate memory for maple bus dma */ - retval = maple_get_dma_buffer(); - if (retval) { - dev_err(&maple_bus, "failed to allocate DMA buffers\n"); - goto cleanup_basic; - } - - /* set up DMA interrupt handler */ - retval = maple_set_dma_interrupt_handler(); - if (retval) { - dev_err(&maple_bus, "bus failed to grab maple " - "DMA IRQ\n"); - goto cleanup_dma; - } - - /* set up VBLANK interrupt handler */ - retval = maple_set_vblank_interrupt_handler(); - if (retval) { - dev_err(&maple_bus, "bus failed to grab VBLANK IRQ\n"); - goto cleanup_irq; - } - - maple_queue_cache = KMEM_CACHE(maple_buffer, SLAB_HWCACHE_ALIGN); - - if (!maple_queue_cache) { - retval = -ENOMEM; - goto cleanup_bothirqs; - } - - INIT_LIST_HEAD(&maple_waitq); - INIT_LIST_HEAD(&maple_sentq); - - /* setup maple ports */ - for (i = 0; i < MAPLE_PORTS; i++) { - checked[i] = false; - empty[i] = false; - mdev[i] = maple_alloc_dev(i, 0); - if (!mdev[i]) { - while (i-- > 0) - maple_free_dev(mdev[i]); - retval = -ENOMEM; - goto cleanup_cache; - } - baseunits[i] = mdev[i]; - atomic_set(&mdev[i]->busy, 1); - maple_add_packet(mdev[i], 0, MAPLE_COMMAND_DEVINFO, 0, NULL); - subdevice_map[i] = 0; - } - - maple_pnp_time = jiffies + HZ; - /* prepare initial queue */ - maple_send(); - dev_info(&maple_bus, "bus core now registered\n"); - - return 0; - -cleanup_cache: - kmem_cache_destroy(maple_queue_cache); - -cleanup_bothirqs: - free_irq(HW_EVENT_VSYNC, 0); - -cleanup_irq: - free_irq(HW_EVENT_MAPLE_DMA, 0); - -cleanup_dma: - free_pages((unsigned long) maple_sendbuf, MAPLE_DMA_PAGES); - -cleanup_basic: - driver_unregister(&maple_unsupported_device.drv); - -cleanup_bus: - bus_unregister(&maple_bus_type); - -cleanup_device: - device_unregister(&maple_bus); - -cleanup: - printk(KERN_ERR "Maple bus registration failed\n"); - return retval; -} -/* Push init to later to ensure hardware gets detected */ -fs_initcall(maple_bus_init); diff --git a/drivers/sh/pm_runtime.c b/drivers/sh/pm_runtime.c deleted file mode 100644 index c887ecdaf19b7c..00000000000000 --- a/drivers/sh/pm_runtime.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Runtime PM support code - * - * Copyright (C) 2009-2010 Magnus Damm - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static struct dev_pm_domain default_pm_domain = { - .ops = { - USE_PM_CLK_RUNTIME_OPS - USE_PLATFORM_PM_SLEEP_OPS - }, -}; - -static struct pm_clk_notifier_block platform_bus_notifier = { - .pm_domain = &default_pm_domain, - .con_ids = { NULL, }, -}; - -static int __init sh_pm_runtime_init(void) -{ - pm_clk_add_notifier(&platform_bus_type, &platform_bus_notifier); - return 0; -} -core_initcall(sh_pm_runtime_init); diff --git a/drivers/sh/superhyway/Makefile b/drivers/sh/superhyway/Makefile deleted file mode 100644 index 6dfa41f160af6b..00000000000000 --- a/drivers/sh/superhyway/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0-only -# -# Makefile for the SuperHyway bus drivers. -# - -obj-$(CONFIG_SUPERHYWAY) += superhyway.o -obj-$(CONFIG_SYSFS) += superhyway-sysfs.o - diff --git a/drivers/sh/superhyway/superhyway-sysfs.c b/drivers/sh/superhyway/superhyway-sysfs.c deleted file mode 100644 index 774f31b564f8f8..00000000000000 --- a/drivers/sh/superhyway/superhyway-sysfs.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * drivers/sh/superhyway/superhyway-sysfs.c - * - * SuperHyway Bus sysfs interface - * - * Copyright (C) 2004, 2005 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include - -#define superhyway_ro_attr(name, fmt, field) \ -static ssize_t name##_show(struct device *dev, struct device_attribute *attr, char *buf) \ -{ \ - struct superhyway_device *s = to_superhyway_device(dev); \ - return sprintf(buf, fmt, s->field); \ -} \ -static DEVICE_ATTR_RO(name); - -/* VCR flags */ -superhyway_ro_attr(perr_flags, "0x%02x\n", vcr.perr_flags); -superhyway_ro_attr(merr_flags, "0x%02x\n", vcr.merr_flags); -superhyway_ro_attr(mod_vers, "0x%04x\n", vcr.mod_vers); -superhyway_ro_attr(mod_id, "0x%04x\n", vcr.mod_id); -superhyway_ro_attr(bot_mb, "0x%02x\n", vcr.bot_mb); -superhyway_ro_attr(top_mb, "0x%02x\n", vcr.top_mb); - -/* Misc */ -superhyway_ro_attr(resource, "0x%08lx\n", resource[0].start); - -static struct attribute *superhyway_dev_attrs[] = { - &dev_attr_perr_flags.attr, - &dev_attr_merr_flags.attr, - &dev_attr_mod_vers.attr, - &dev_attr_mod_id.attr, - &dev_attr_bot_mb.attr, - &dev_attr_top_mb.attr, - &dev_attr_resource.attr, - NULL, -}; - -static const struct attribute_group superhyway_dev_group = { - .attrs = superhyway_dev_attrs, -}; - -const struct attribute_group *superhyway_dev_groups[] = { - &superhyway_dev_group, - NULL, -}; diff --git a/drivers/sh/superhyway/superhyway.c b/drivers/sh/superhyway/superhyway.c deleted file mode 100644 index 44324abe21dada..00000000000000 --- a/drivers/sh/superhyway/superhyway.c +++ /dev/null @@ -1,234 +0,0 @@ -/* - * drivers/sh/superhyway/superhyway.c - * - * SuperHyway Bus Driver - * - * Copyright (C) 2004, 2005 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static int superhyway_devices; - -static struct device superhyway_bus_device = { - .init_name = "superhyway", -}; - -static void superhyway_device_release(struct device *dev) -{ - struct superhyway_device *sdev = to_superhyway_device(dev); - - kfree(sdev->resource); - kfree(sdev); -} - -/** - * superhyway_add_device - Add a SuperHyway module - * @base: Physical address where module is mapped. - * @sdev: SuperHyway device to add, or NULL to allocate a new one. - * @bus: Bus where SuperHyway module resides. - * - * This is responsible for adding a new SuperHyway module. This sets up a new - * struct superhyway_device for the module being added if @sdev == NULL. - * - * Devices are initially added in the order that they are scanned (from the - * top-down of the memory map), and are assigned an ID based on the order that - * they are added. Any manual addition of a module will thus get the ID after - * the devices already discovered regardless of where it resides in memory. - * - * Further work can and should be done in superhyway_scan_bus(), to be sure - * that any new modules are properly discovered and subsequently registered. - */ -int superhyway_add_device(unsigned long base, struct superhyway_device *sdev, - struct superhyway_bus *bus) -{ - struct superhyway_device *dev = sdev; - - if (!dev) { - dev = kzalloc(sizeof(struct superhyway_device), GFP_KERNEL); - if (!dev) - return -ENOMEM; - - } - - dev->bus = bus; - superhyway_read_vcr(dev, base, &dev->vcr); - - if (!dev->resource) { - dev->resource = kzalloc(sizeof(struct resource), GFP_KERNEL); - if (!dev->resource) { - kfree(dev); - return -ENOMEM; - } - - dev->resource->name = dev->name; - dev->resource->start = base; - dev->resource->end = dev->resource->start + 0x01000000; - } - - dev->dev.parent = &superhyway_bus_device; - dev->dev.bus = &superhyway_bus_type; - dev->dev.release = superhyway_device_release; - dev->id.id = dev->vcr.mod_id; - - sprintf(dev->name, "SuperHyway device %04x", dev->id.id); - dev_set_name(&dev->dev, "%02x", superhyway_devices); - - superhyway_devices++; - - return device_register(&dev->dev); -} - -int superhyway_add_devices(struct superhyway_bus *bus, - struct superhyway_device **devices, - int nr_devices) -{ - int i, ret = 0; - - for (i = 0; i < nr_devices; i++) { - struct superhyway_device *dev = devices[i]; - ret |= superhyway_add_device(dev->resource[0].start, dev, bus); - } - - return ret; -} - -static int __init superhyway_init(void) -{ - struct superhyway_bus *bus; - int ret; - - ret = device_register(&superhyway_bus_device); - if (unlikely(ret)) - return ret; - - for (bus = superhyway_channels; bus->ops; bus++) - ret |= superhyway_scan_bus(bus); - - return ret; -} -postcore_initcall(superhyway_init); - -static const struct superhyway_device_id * -superhyway_match_id(const struct superhyway_device_id *ids, - struct superhyway_device *dev) -{ - while (ids->id) { - if (ids->id == dev->id.id) - return ids; - - ids++; - } - - return NULL; -} - -static int superhyway_device_probe(struct device *dev) -{ - struct superhyway_device *shyway_dev = to_superhyway_device(dev); - struct superhyway_driver *shyway_drv = to_superhyway_driver(dev->driver); - - if (shyway_drv && shyway_drv->probe) { - const struct superhyway_device_id *id; - - id = superhyway_match_id(shyway_drv->id_table, shyway_dev); - if (id) - return shyway_drv->probe(shyway_dev, id); - } - - return -ENODEV; -} - -static void superhyway_device_remove(struct device *dev) -{ - struct superhyway_device *shyway_dev = to_superhyway_device(dev); - struct superhyway_driver *shyway_drv = to_superhyway_driver(dev->driver); - - if (shyway_drv->remove) - shyway_drv->remove(shyway_dev); -} - -/** - * superhyway_register_driver - Register a new SuperHyway driver - * @drv: SuperHyway driver to register. - * - * This registers the passed in @drv. Any devices matching the id table will - * automatically be populated and handed off to the driver's specified probe - * routine. - */ -int superhyway_register_driver(struct superhyway_driver *drv) -{ - drv->drv.name = drv->name; - drv->drv.bus = &superhyway_bus_type; - - return driver_register(&drv->drv); -} - -/** - * superhyway_unregister_driver - Unregister a SuperHyway driver - * @drv: SuperHyway driver to unregister. - * - * This cleans up after superhyway_register_driver(), and should be invoked in - * the exit path of any module drivers. - */ -void superhyway_unregister_driver(struct superhyway_driver *drv) -{ - driver_unregister(&drv->drv); -} - -static int superhyway_bus_match(struct device *dev, struct device_driver *drv) -{ - struct superhyway_device *shyway_dev = to_superhyway_device(dev); - struct superhyway_driver *shyway_drv = to_superhyway_driver(drv); - const struct superhyway_device_id *ids = shyway_drv->id_table; - - if (!ids) - return -EINVAL; - if (superhyway_match_id(ids, shyway_dev)) - return 1; - - return -ENODEV; -} - -struct bus_type superhyway_bus_type = { - .name = "superhyway", - .match = superhyway_bus_match, -#ifdef CONFIG_SYSFS - .dev_groups = superhyway_dev_groups, -#endif - .probe = superhyway_device_probe, - .remove = superhyway_device_remove, -}; - -static int __init superhyway_bus_init(void) -{ - return bus_register(&superhyway_bus_type); -} - -static void __exit superhyway_bus_exit(void) -{ - device_unregister(&superhyway_bus_device); - bus_unregister(&superhyway_bus_type); -} - -core_initcall(superhyway_bus_init); -module_exit(superhyway_bus_exit); - -EXPORT_SYMBOL(superhyway_bus_type); -EXPORT_SYMBOL(superhyway_add_device); -EXPORT_SYMBOL(superhyway_add_devices); -EXPORT_SYMBOL(superhyway_register_driver); -EXPORT_SYMBOL(superhyway_unregister_driver); - -MODULE_LICENSE("GPL"); diff --git a/include/linux/sh_clk.h b/include/linux/sh_clk.h deleted file mode 100644 index 7bed5be886c657..00000000000000 --- a/include/linux/sh_clk.h +++ /dev/null @@ -1,213 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef __SH_CLOCK_H -#define __SH_CLOCK_H - -#include -#include -#include -#include -#include -#include -#include - -struct clk; - -struct clk_mapping { - phys_addr_t phys; - void __iomem *base; - unsigned long len; - struct kref ref; -}; - -struct sh_clk_ops { -#ifdef CONFIG_SH_CLK_CPG_LEGACY - void (*init)(struct clk *clk); -#endif - int (*enable)(struct clk *clk); - void (*disable)(struct clk *clk); - unsigned long (*recalc)(struct clk *clk); - int (*set_rate)(struct clk *clk, unsigned long rate); - int (*set_parent)(struct clk *clk, struct clk *parent); - long (*round_rate)(struct clk *clk, unsigned long rate); -}; - -#define SH_CLK_DIV_MSK(div) ((1 << (div)) - 1) -#define SH_CLK_DIV4_MSK SH_CLK_DIV_MSK(4) -#define SH_CLK_DIV6_MSK SH_CLK_DIV_MSK(6) - -struct clk { - struct list_head node; - struct clk *parent; - struct clk **parent_table; /* list of parents to */ - unsigned short parent_num; /* choose between */ - unsigned char src_shift; /* source clock field in the */ - unsigned char src_width; /* configuration register */ - struct sh_clk_ops *ops; - - struct list_head children; - struct list_head sibling; /* node for children */ - - int usecount; - - unsigned long rate; - unsigned long flags; - - void __iomem *enable_reg; - void __iomem *status_reg; - unsigned int enable_bit; - void __iomem *mapped_reg; - - unsigned int div_mask; - unsigned long arch_flags; - void *priv; - struct clk_mapping *mapping; - struct cpufreq_frequency_table *freq_table; - unsigned int nr_freqs; -}; - -#define CLK_ENABLE_ON_INIT BIT(0) - -#define CLK_ENABLE_REG_32BIT BIT(1) /* default access size */ -#define CLK_ENABLE_REG_16BIT BIT(2) -#define CLK_ENABLE_REG_8BIT BIT(3) - -#define CLK_MASK_DIV_ON_DISABLE BIT(4) - -#define CLK_ENABLE_REG_MASK (CLK_ENABLE_REG_32BIT | \ - CLK_ENABLE_REG_16BIT | \ - CLK_ENABLE_REG_8BIT) - -/* drivers/sh/clk.c */ -unsigned long followparent_recalc(struct clk *); -void recalculate_root_clocks(void); -void propagate_rate(struct clk *); -int clk_reparent(struct clk *child, struct clk *parent); -int clk_register(struct clk *); -void clk_unregister(struct clk *); -void clk_enable_init_clocks(void); - -struct clk_div_mult_table { - unsigned int *divisors; - unsigned int nr_divisors; - unsigned int *multipliers; - unsigned int nr_multipliers; -}; - -struct cpufreq_frequency_table; -void clk_rate_table_build(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - int nr_freqs, - struct clk_div_mult_table *src_table, - unsigned long *bitmap); - -long clk_rate_table_round(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - unsigned long rate); - -int clk_rate_table_find(struct clk *clk, - struct cpufreq_frequency_table *freq_table, - unsigned long rate); - -long clk_rate_div_range_round(struct clk *clk, unsigned int div_min, - unsigned int div_max, unsigned long rate); - -long clk_rate_mult_range_round(struct clk *clk, unsigned int mult_min, - unsigned int mult_max, unsigned long rate); - -#define SH_CLK_MSTP(_parent, _enable_reg, _enable_bit, _status_reg, _flags) \ -{ \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_enable_reg, \ - .enable_bit = _enable_bit, \ - .status_reg = _status_reg, \ - .flags = _flags, \ -} - -#define SH_CLK_MSTP32(_p, _r, _b, _f) \ - SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_32BIT) - -#define SH_CLK_MSTP32_STS(_p, _r, _b, _s, _f) \ - SH_CLK_MSTP(_p, _r, _b, _s, _f | CLK_ENABLE_REG_32BIT) - -#define SH_CLK_MSTP16(_p, _r, _b, _f) \ - SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_16BIT) - -#define SH_CLK_MSTP8(_p, _r, _b, _f) \ - SH_CLK_MSTP(_p, _r, _b, 0, _f | CLK_ENABLE_REG_8BIT) - -int sh_clk_mstp_register(struct clk *clks, int nr); - -/* - * MSTP registration never really cared about access size, despite the - * original enable/disable pairs assuming a 32-bit access. Clocks are - * responsible for defining their access sizes either directly or via the - * clock definition wrappers. - */ -static inline int __deprecated sh_clk_mstp32_register(struct clk *clks, int nr) -{ - return sh_clk_mstp_register(clks, nr); -} - -#define SH_CLK_DIV4(_parent, _reg, _shift, _div_bitmap, _flags) \ -{ \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_reg, \ - .enable_bit = _shift, \ - .arch_flags = _div_bitmap, \ - .div_mask = SH_CLK_DIV4_MSK, \ - .flags = _flags, \ -} - -struct clk_div_table { - struct clk_div_mult_table *div_mult_table; - void (*kick)(struct clk *clk); -}; - -#define clk_div4_table clk_div_table - -int sh_clk_div4_register(struct clk *clks, int nr, - struct clk_div4_table *table); -int sh_clk_div4_enable_register(struct clk *clks, int nr, - struct clk_div4_table *table); -int sh_clk_div4_reparent_register(struct clk *clks, int nr, - struct clk_div4_table *table); - -#define SH_CLK_DIV6_EXT(_reg, _flags, _parents, \ - _num_parents, _src_shift, _src_width) \ -{ \ - .enable_reg = (void __iomem *)_reg, \ - .enable_bit = 0, /* unused */ \ - .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \ - .div_mask = SH_CLK_DIV6_MSK, \ - .parent_table = _parents, \ - .parent_num = _num_parents, \ - .src_shift = _src_shift, \ - .src_width = _src_width, \ -} - -#define SH_CLK_DIV6(_parent, _reg, _flags) \ -{ \ - .parent = _parent, \ - .enable_reg = (void __iomem *)_reg, \ - .enable_bit = 0, /* unused */ \ - .div_mask = SH_CLK_DIV6_MSK, \ - .flags = _flags | CLK_MASK_DIV_ON_DISABLE, \ -} - -int sh_clk_div6_register(struct clk *clks, int nr); -int sh_clk_div6_reparent_register(struct clk *clks, int nr); - -#define CLKDEV_CON_ID(_id, _clk) { .con_id = _id, .clk = _clk } -#define CLKDEV_DEV_ID(_id, _clk) { .dev_id = _id, .clk = _clk } -#define CLKDEV_ICK_ID(_cid, _did, _clk) { .con_id = _cid, .dev_id = _did, .clk = _clk } - -/* .enable_reg will be updated to .mapping on sh_clk_fsidiv_register() */ -#define SH_CLK_FSIDIV(_reg, _parent) \ -{ \ - .enable_reg = (void __iomem *)_reg, \ - .parent = _parent, \ -} - -int sh_clk_fsidiv_register(struct clk *clks, int nr); - -#endif /* __SH_CLOCK_H */ diff --git a/include/linux/superhyway.h b/include/linux/superhyway.h deleted file mode 100644 index 8d3376775813d3..00000000000000 --- a/include/linux/superhyway.h +++ /dev/null @@ -1,107 +0,0 @@ -/* - * include/linux/superhyway.h - * - * SuperHyway Bus definitions - * - * Copyright (C) 2004, 2005 Paul Mundt - * - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - */ -#ifndef __LINUX_SUPERHYWAY_H -#define __LINUX_SUPERHYWAY_H - -#include - -/* - * SuperHyway IDs - */ -#define SUPERHYWAY_DEVICE_ID_SH5_DMAC 0x0183 - -struct superhyway_vcr_info { - u8 perr_flags; /* P-port Error flags */ - u8 merr_flags; /* Module Error flags */ - u16 mod_vers; /* Module Version */ - u16 mod_id; /* Module ID */ - u8 bot_mb; /* Bottom Memory block */ - u8 top_mb; /* Top Memory block */ -}; - -struct superhyway_ops { - int (*read_vcr)(unsigned long base, struct superhyway_vcr_info *vcr); - int (*write_vcr)(unsigned long base, struct superhyway_vcr_info vcr); -}; - -struct superhyway_bus { - struct superhyway_ops *ops; -}; - -extern struct superhyway_bus superhyway_channels[]; - -struct superhyway_device_id { - unsigned int id; - unsigned long driver_data; -}; - -struct superhyway_device; -extern struct bus_type superhyway_bus_type; - -struct superhyway_driver { - char *name; - - const struct superhyway_device_id *id_table; - struct device_driver drv; - - int (*probe)(struct superhyway_device *dev, const struct superhyway_device_id *id); - void (*remove)(struct superhyway_device *dev); -}; - -#define to_superhyway_driver(d) container_of((d), struct superhyway_driver, drv) - -struct superhyway_device { - char name[32]; - - struct device dev; - - struct superhyway_device_id id; - struct superhyway_driver *drv; - struct superhyway_bus *bus; - - int num_resources; - struct resource *resource; - struct superhyway_vcr_info vcr; -}; - -#define to_superhyway_device(d) container_of((d), struct superhyway_device, dev) - -#define superhyway_get_drvdata(d) dev_get_drvdata(&(d)->dev) -#define superhyway_set_drvdata(d,p) dev_set_drvdata(&(d)->dev, (p)) - -static inline int -superhyway_read_vcr(struct superhyway_device *dev, unsigned long base, - struct superhyway_vcr_info *vcr) -{ - return dev->bus->ops->read_vcr(base, vcr); -} - -static inline int -superhyway_write_vcr(struct superhyway_device *dev, unsigned long base, - struct superhyway_vcr_info vcr) -{ - return dev->bus->ops->write_vcr(base, vcr); -} - -extern int superhyway_scan_bus(struct superhyway_bus *); - -/* drivers/sh/superhyway/superhyway.c */ -int superhyway_register_driver(struct superhyway_driver *); -void superhyway_unregister_driver(struct superhyway_driver *); -int superhyway_add_device(unsigned long base, struct superhyway_device *, struct superhyway_bus *); -int superhyway_add_devices(struct superhyway_bus *bus, struct superhyway_device **devices, int nr_devices); - -/* drivers/sh/superhyway/superhyway-sysfs.c */ -extern const struct attribute_group *superhyway_dev_groups[]; - -#endif /* __LINUX_SUPERHYWAY_H */ - From patchwork Fri Jan 13 06:23:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642270 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 38EB7C678D7 for ; Fri, 13 Jan 2023 06:29:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240800AbjAMG3f (ORCPT ); Fri, 13 Jan 2023 01:29:35 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:36742 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240696AbjAMG0G (ORCPT ); Fri, 13 Jan 2023 01:26:06 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 681155A880; Thu, 12 Jan 2023 22:24:48 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=brkgyM1hhrmjLwT1BCvS491OM9ZvmSvWuQcY6ZdmaEQ=; b=rclg5IcyZx3hAYAW2A82gKgG/R 9h9Oe/wM1Koo+NmcZ4yMIJIFj+qyIun0yWyAuormOj2yAyWxmpqiP2tOTjglLnHiXw+LO8ETgIdA+ 5Svhx7nVkyRr8shQSGKZC980O+hinT+yIkJMia9iivbaAqpxScAjdfS1ylAfFTuFfEpPajKlizKuC x920Cmh9IN6hilV+vdW649ilBNPtNcRIhR92SLyVFpjckwWhuUlUQEzckeqR1pXS3MdV0ZyVfntjY 4ZjNun8OKq1jiBsWb6I8b5g9mXdhx5n98DESlAo/jfRw7Kht5JW4J78GkDbW2pZIH+YhQxqch531J NCRDTDXw==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUT-000lua-TT; Fri, 13 Jan 2023 06:24:38 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 15/22] spi: remove spi-sh Date: Fri, 13 Jan 2023 07:23:32 +0100 Message-Id: <20230113062339.1909087-16-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/spi/Kconfig | 6 - drivers/spi/Makefile | 1 - drivers/spi/spi-sh.c | 474 ------------------------------------------- 3 files changed, 481 deletions(-) delete mode 100644 drivers/spi/spi-sh.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 2c5226adf5e1d3..7508dcef909c78 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -882,12 +882,6 @@ config SPI_SH_MSIOF help SPI driver for SuperH and SH Mobile MSIOF blocks. -config SPI_SH - tristate "SuperH SPI controller" - depends on SUPERH || COMPILE_TEST - help - SPI driver for SuperH SPI blocks. - config SPI_SH_SCI tristate "SuperH SCI SPI controller" depends on SUPERH diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index be9ba40ef8d03d..342a7eb5181c9b 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -116,7 +116,6 @@ obj-$(CONFIG_SPI_S3C24XX) += spi-s3c24xx-hw.o spi-s3c24xx-hw-y := spi-s3c24xx.o obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o -obj-$(CONFIG_SPI_SH) += spi-sh.o obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o diff --git a/drivers/spi/spi-sh.c b/drivers/spi/spi-sh.c deleted file mode 100644 index 3e72fad99adfd4..00000000000000 --- a/drivers/spi/spi-sh.c +++ /dev/null @@ -1,474 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * SH SPI bus driver - * - * Copyright (C) 2011 Renesas Solutions Corp. - * - * Based on pxa2xx_spi.c: - * Copyright (C) 2005 Stephen Street / StreetFire Sound Labs - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define SPI_SH_TBR 0x00 -#define SPI_SH_RBR 0x00 -#define SPI_SH_CR1 0x08 -#define SPI_SH_CR2 0x10 -#define SPI_SH_CR3 0x18 -#define SPI_SH_CR4 0x20 -#define SPI_SH_CR5 0x28 - -/* CR1 */ -#define SPI_SH_TBE 0x80 -#define SPI_SH_TBF 0x40 -#define SPI_SH_RBE 0x20 -#define SPI_SH_RBF 0x10 -#define SPI_SH_PFONRD 0x08 -#define SPI_SH_SSDB 0x04 -#define SPI_SH_SSD 0x02 -#define SPI_SH_SSA 0x01 - -/* CR2 */ -#define SPI_SH_RSTF 0x80 -#define SPI_SH_LOOPBK 0x40 -#define SPI_SH_CPOL 0x20 -#define SPI_SH_CPHA 0x10 -#define SPI_SH_L1M0 0x08 - -/* CR3 */ -#define SPI_SH_MAX_BYTE 0xFF - -/* CR4 */ -#define SPI_SH_TBEI 0x80 -#define SPI_SH_TBFI 0x40 -#define SPI_SH_RBEI 0x20 -#define SPI_SH_RBFI 0x10 -#define SPI_SH_WPABRT 0x04 -#define SPI_SH_SSS 0x01 - -/* CR8 */ -#define SPI_SH_P1L0 0x80 -#define SPI_SH_PP1L0 0x40 -#define SPI_SH_MUXI 0x20 -#define SPI_SH_MUXIRQ 0x10 - -#define SPI_SH_FIFO_SIZE 32 -#define SPI_SH_SEND_TIMEOUT (3 * HZ) -#define SPI_SH_RECEIVE_TIMEOUT (HZ >> 3) - -#undef DEBUG - -struct spi_sh_data { - void __iomem *addr; - int irq; - struct spi_master *master; - unsigned long cr1; - wait_queue_head_t wait; - int width; -}; - -static void spi_sh_write(struct spi_sh_data *ss, unsigned long data, - unsigned long offset) -{ - if (ss->width == 8) - iowrite8(data, ss->addr + (offset >> 2)); - else if (ss->width == 32) - iowrite32(data, ss->addr + offset); -} - -static unsigned long spi_sh_read(struct spi_sh_data *ss, unsigned long offset) -{ - if (ss->width == 8) - return ioread8(ss->addr + (offset >> 2)); - else if (ss->width == 32) - return ioread32(ss->addr + offset); - else - return 0; -} - -static void spi_sh_set_bit(struct spi_sh_data *ss, unsigned long val, - unsigned long offset) -{ - unsigned long tmp; - - tmp = spi_sh_read(ss, offset); - tmp |= val; - spi_sh_write(ss, tmp, offset); -} - -static void spi_sh_clear_bit(struct spi_sh_data *ss, unsigned long val, - unsigned long offset) -{ - unsigned long tmp; - - tmp = spi_sh_read(ss, offset); - tmp &= ~val; - spi_sh_write(ss, tmp, offset); -} - -static void clear_fifo(struct spi_sh_data *ss) -{ - spi_sh_set_bit(ss, SPI_SH_RSTF, SPI_SH_CR2); - spi_sh_clear_bit(ss, SPI_SH_RSTF, SPI_SH_CR2); -} - -static int spi_sh_wait_receive_buffer(struct spi_sh_data *ss) -{ - int timeout = 100000; - - while (spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_RBE) { - udelay(10); - if (timeout-- < 0) - return -ETIMEDOUT; - } - return 0; -} - -static int spi_sh_wait_write_buffer_empty(struct spi_sh_data *ss) -{ - int timeout = 100000; - - while (!(spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_TBE)) { - udelay(10); - if (timeout-- < 0) - return -ETIMEDOUT; - } - return 0; -} - -static int spi_sh_send(struct spi_sh_data *ss, struct spi_message *mesg, - struct spi_transfer *t) -{ - int i, retval = 0; - int remain = t->len; - int cur_len; - unsigned char *data; - long ret; - - if (t->len) - spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); - - data = (unsigned char *)t->tx_buf; - while (remain > 0) { - cur_len = min(SPI_SH_FIFO_SIZE, remain); - for (i = 0; i < cur_len && - !(spi_sh_read(ss, SPI_SH_CR4) & - SPI_SH_WPABRT) && - !(spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_TBF); - i++) - spi_sh_write(ss, (unsigned long)data[i], SPI_SH_TBR); - - if (spi_sh_read(ss, SPI_SH_CR4) & SPI_SH_WPABRT) { - /* Abort SPI operation */ - spi_sh_set_bit(ss, SPI_SH_WPABRT, SPI_SH_CR4); - retval = -EIO; - break; - } - - cur_len = i; - - remain -= cur_len; - data += cur_len; - - if (remain > 0) { - ss->cr1 &= ~SPI_SH_TBE; - spi_sh_set_bit(ss, SPI_SH_TBE, SPI_SH_CR4); - ret = wait_event_interruptible_timeout(ss->wait, - ss->cr1 & SPI_SH_TBE, - SPI_SH_SEND_TIMEOUT); - if (ret == 0 && !(ss->cr1 & SPI_SH_TBE)) { - printk(KERN_ERR "%s: timeout\n", __func__); - return -ETIMEDOUT; - } - } - } - - if (list_is_last(&t->transfer_list, &mesg->transfers)) { - spi_sh_clear_bit(ss, SPI_SH_SSD | SPI_SH_SSDB, SPI_SH_CR1); - spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); - - ss->cr1 &= ~SPI_SH_TBE; - spi_sh_set_bit(ss, SPI_SH_TBE, SPI_SH_CR4); - ret = wait_event_interruptible_timeout(ss->wait, - ss->cr1 & SPI_SH_TBE, - SPI_SH_SEND_TIMEOUT); - if (ret == 0 && (ss->cr1 & SPI_SH_TBE)) { - printk(KERN_ERR "%s: timeout\n", __func__); - return -ETIMEDOUT; - } - } - - return retval; -} - -static int spi_sh_receive(struct spi_sh_data *ss, struct spi_message *mesg, - struct spi_transfer *t) -{ - int i; - int remain = t->len; - int cur_len; - unsigned char *data; - long ret; - - if (t->len > SPI_SH_MAX_BYTE) - spi_sh_write(ss, SPI_SH_MAX_BYTE, SPI_SH_CR3); - else - spi_sh_write(ss, t->len, SPI_SH_CR3); - - spi_sh_clear_bit(ss, SPI_SH_SSD | SPI_SH_SSDB, SPI_SH_CR1); - spi_sh_set_bit(ss, SPI_SH_SSA, SPI_SH_CR1); - - spi_sh_wait_write_buffer_empty(ss); - - data = (unsigned char *)t->rx_buf; - while (remain > 0) { - if (remain >= SPI_SH_FIFO_SIZE) { - ss->cr1 &= ~SPI_SH_RBF; - spi_sh_set_bit(ss, SPI_SH_RBF, SPI_SH_CR4); - ret = wait_event_interruptible_timeout(ss->wait, - ss->cr1 & SPI_SH_RBF, - SPI_SH_RECEIVE_TIMEOUT); - if (ret == 0 && - spi_sh_read(ss, SPI_SH_CR1) & SPI_SH_RBE) { - printk(KERN_ERR "%s: timeout\n", __func__); - return -ETIMEDOUT; - } - } - - cur_len = min(SPI_SH_FIFO_SIZE, remain); - for (i = 0; i < cur_len; i++) { - if (spi_sh_wait_receive_buffer(ss)) - break; - data[i] = (unsigned char)spi_sh_read(ss, SPI_SH_RBR); - } - - remain -= cur_len; - data += cur_len; - } - - /* deassert CS when SPI is receiving. */ - if (t->len > SPI_SH_MAX_BYTE) { - clear_fifo(ss); - spi_sh_write(ss, 1, SPI_SH_CR3); - } else { - spi_sh_write(ss, 0, SPI_SH_CR3); - } - - return 0; -} - -static int spi_sh_transfer_one_message(struct spi_controller *ctlr, - struct spi_message *mesg) -{ - struct spi_sh_data *ss = spi_controller_get_devdata(ctlr); - struct spi_transfer *t; - int ret; - - pr_debug("%s: enter\n", __func__); - - spi_sh_clear_bit(ss, SPI_SH_SSA, SPI_SH_CR1); - - list_for_each_entry(t, &mesg->transfers, transfer_list) { - pr_debug("tx_buf = %p, rx_buf = %p\n", - t->tx_buf, t->rx_buf); - pr_debug("len = %d, delay.value = %d\n", - t->len, t->delay.value); - - if (t->tx_buf) { - ret = spi_sh_send(ss, mesg, t); - if (ret < 0) - goto error; - } - if (t->rx_buf) { - ret = spi_sh_receive(ss, mesg, t); - if (ret < 0) - goto error; - } - mesg->actual_length += t->len; - } - - mesg->status = 0; - spi_finalize_current_message(ctlr); - - clear_fifo(ss); - spi_sh_set_bit(ss, SPI_SH_SSD, SPI_SH_CR1); - udelay(100); - - spi_sh_clear_bit(ss, SPI_SH_SSA | SPI_SH_SSDB | SPI_SH_SSD, - SPI_SH_CR1); - - clear_fifo(ss); - - return 0; - - error: - mesg->status = ret; - spi_finalize_current_message(ctlr); - if (mesg->complete) - mesg->complete(mesg->context); - - spi_sh_clear_bit(ss, SPI_SH_SSA | SPI_SH_SSDB | SPI_SH_SSD, - SPI_SH_CR1); - clear_fifo(ss); - - return ret; -} - -static int spi_sh_setup(struct spi_device *spi) -{ - struct spi_sh_data *ss = spi_master_get_devdata(spi->master); - - pr_debug("%s: enter\n", __func__); - - spi_sh_write(ss, 0xfe, SPI_SH_CR1); /* SPI sycle stop */ - spi_sh_write(ss, 0x00, SPI_SH_CR1); /* CR1 init */ - spi_sh_write(ss, 0x00, SPI_SH_CR3); /* CR3 init */ - - clear_fifo(ss); - - /* 1/8 clock */ - spi_sh_write(ss, spi_sh_read(ss, SPI_SH_CR2) | 0x07, SPI_SH_CR2); - udelay(10); - - return 0; -} - -static void spi_sh_cleanup(struct spi_device *spi) -{ - struct spi_sh_data *ss = spi_master_get_devdata(spi->master); - - pr_debug("%s: enter\n", __func__); - - spi_sh_clear_bit(ss, SPI_SH_SSA | SPI_SH_SSDB | SPI_SH_SSD, - SPI_SH_CR1); -} - -static irqreturn_t spi_sh_irq(int irq, void *_ss) -{ - struct spi_sh_data *ss = (struct spi_sh_data *)_ss; - unsigned long cr1; - - cr1 = spi_sh_read(ss, SPI_SH_CR1); - if (cr1 & SPI_SH_TBE) - ss->cr1 |= SPI_SH_TBE; - if (cr1 & SPI_SH_TBF) - ss->cr1 |= SPI_SH_TBF; - if (cr1 & SPI_SH_RBE) - ss->cr1 |= SPI_SH_RBE; - if (cr1 & SPI_SH_RBF) - ss->cr1 |= SPI_SH_RBF; - - if (ss->cr1) { - spi_sh_clear_bit(ss, ss->cr1, SPI_SH_CR4); - wake_up(&ss->wait); - } - - return IRQ_HANDLED; -} - -static int spi_sh_remove(struct platform_device *pdev) -{ - struct spi_sh_data *ss = platform_get_drvdata(pdev); - - spi_unregister_master(ss->master); - free_irq(ss->irq, ss); - - return 0; -} - -static int spi_sh_probe(struct platform_device *pdev) -{ - struct resource *res; - struct spi_master *master; - struct spi_sh_data *ss; - int ret, irq; - - /* get base addr */ - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (unlikely(res == NULL)) { - dev_err(&pdev->dev, "invalid resource\n"); - return -EINVAL; - } - - irq = platform_get_irq(pdev, 0); - if (irq < 0) - return irq; - - master = devm_spi_alloc_master(&pdev->dev, sizeof(struct spi_sh_data)); - if (master == NULL) { - dev_err(&pdev->dev, "spi_alloc_master error.\n"); - return -ENOMEM; - } - - ss = spi_master_get_devdata(master); - platform_set_drvdata(pdev, ss); - - switch (res->flags & IORESOURCE_MEM_TYPE_MASK) { - case IORESOURCE_MEM_8BIT: - ss->width = 8; - break; - case IORESOURCE_MEM_32BIT: - ss->width = 32; - break; - default: - dev_err(&pdev->dev, "No support width\n"); - return -ENODEV; - } - ss->irq = irq; - ss->master = master; - ss->addr = devm_ioremap(&pdev->dev, res->start, resource_size(res)); - if (ss->addr == NULL) { - dev_err(&pdev->dev, "ioremap error.\n"); - return -ENOMEM; - } - init_waitqueue_head(&ss->wait); - - ret = request_irq(irq, spi_sh_irq, 0, "spi_sh", ss); - if (ret < 0) { - dev_err(&pdev->dev, "request_irq error\n"); - return ret; - } - - master->num_chipselect = 2; - master->bus_num = pdev->id; - master->setup = spi_sh_setup; - master->transfer_one_message = spi_sh_transfer_one_message; - master->cleanup = spi_sh_cleanup; - - ret = spi_register_master(master); - if (ret < 0) { - printk(KERN_ERR "spi_register_master error.\n"); - goto error3; - } - - return 0; - - error3: - free_irq(irq, ss); - return ret; -} - -static struct platform_driver spi_sh_driver = { - .probe = spi_sh_probe, - .remove = spi_sh_remove, - .driver = { - .name = "sh_spi", - }, -}; -module_platform_driver(spi_sh_driver); - -MODULE_DESCRIPTION("SH SPI bus driver"); -MODULE_LICENSE("GPL v2"); -MODULE_AUTHOR("Yoshihiro Shimoda"); -MODULE_ALIAS("platform:sh_spi"); From patchwork Fri Jan 13 06:23:33 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642268 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1F33CC678D6 for ; Fri, 13 Jan 2023 06:29:52 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241262AbjAMG3q (ORCPT ); Fri, 13 Jan 2023 01:29:46 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:33444 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240712AbjAMG0N (ORCPT ); Fri, 13 Jan 2023 01:26:13 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52AF759FA7; Thu, 12 Jan 2023 22:24:51 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=4Cn32+DwniiE8Ivc8k8ZYXVlFs6gh/3Rw72W3/GZ4ag=; b=Fve8lBIQorfiJ/FhMD6e1GvYXc rGSPgQTVMyq0dxlP00mFanqHXFeH9t17eVtoz/JRWr+oFTQ0ynGMwYJHt5mfB04KzdaQjOX8Iu9fs nIQCq/R62BjdnWiSBeuBxN7hx5e4sYqYWJU6VIfqx17ddSCZZlu7ubY/3XF9PkfW4XzApYx2Cd9k9 zs2s4D1MofDj9wf4eoTSyb6ybNKwpiGOqGQt9CBguMf+78gDheVOOw6bNmSUU/Blr1SaKqbcwa66y 6cpVyf3vy//XvyjihCdST/c6G+qVI++1b+7abn1kff1W7YyuOYJBrAFCIknOxvbFhCUglhpOxZ9Fo xk7GnO7w==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUW-000lwz-NO; Fri, 13 Jan 2023 06:24:41 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 16/22] spi: remove spi-sh-sci Date: Fri, 13 Jan 2023 07:23:33 +0100 Message-Id: <20230113062339.1909087-17-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org Now that arch/sh is removed this driver is dead code. Signed-off-by: Christoph Hellwig --- drivers/spi/Kconfig | 7 -- drivers/spi/Makefile | 1 - drivers/spi/spi-sh-sci.c | 197 --------------------------------------- 3 files changed, 205 deletions(-) delete mode 100644 drivers/spi/spi-sh-sci.c diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig index 7508dcef909c78..76f3bc6f8c81fc 100644 --- a/drivers/spi/Kconfig +++ b/drivers/spi/Kconfig @@ -882,13 +882,6 @@ config SPI_SH_MSIOF help SPI driver for SuperH and SH Mobile MSIOF blocks. -config SPI_SH_SCI - tristate "SuperH SCI SPI controller" - depends on SUPERH - select SPI_BITBANG - help - SPI driver for SuperH SCI blocks. - config SPI_SH_HSPI tristate "SuperH HSPI controller" depends on ARCH_RENESAS || COMPILE_TEST diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile index 342a7eb5181c9b..27d877440c6539 100644 --- a/drivers/spi/Makefile +++ b/drivers/spi/Makefile @@ -118,7 +118,6 @@ obj-$(CONFIG_SPI_S3C64XX) += spi-s3c64xx.o obj-$(CONFIG_SPI_SC18IS602) += spi-sc18is602.o obj-$(CONFIG_SPI_SH_HSPI) += spi-sh-hspi.o obj-$(CONFIG_SPI_SH_MSIOF) += spi-sh-msiof.o -obj-$(CONFIG_SPI_SH_SCI) += spi-sh-sci.o obj-$(CONFIG_SPI_SIFIVE) += spi-sifive.o obj-$(CONFIG_SPI_SLAVE_MT27XX) += spi-slave-mt27xx.o obj-$(CONFIG_SPI_SN_F_OSPI) += spi-sn-f-ospi.o diff --git a/drivers/spi/spi-sh-sci.c b/drivers/spi/spi-sh-sci.c deleted file mode 100644 index 8f30531e141867..00000000000000 --- a/drivers/spi/spi-sh-sci.c +++ /dev/null @@ -1,197 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * SH SCI SPI interface - * - * Copyright (c) 2008 Magnus Damm - * - * Based on S3C24XX GPIO based SPI driver, which is: - * Copyright (c) 2006 Ben Dooks - * Copyright (c) 2006 Simtec Electronics - */ - -#include -#include -#include -#include - -#include -#include -#include - -#include -#include - -struct sh_sci_spi { - struct spi_bitbang bitbang; - - void __iomem *membase; - unsigned char val; - struct sh_spi_info *info; - struct platform_device *dev; -}; - -#define SCSPTR(sp) (sp->membase + 0x1c) -#define PIN_SCK (1 << 2) -#define PIN_TXD (1 << 0) -#define PIN_RXD PIN_TXD -#define PIN_INIT ((1 << 1) | (1 << 3) | PIN_SCK | PIN_TXD) - -static inline void setbits(struct sh_sci_spi *sp, int bits, int on) -{ - /* - * We are the only user of SCSPTR so no locking is required. - * Reading bit 2 and 0 in SCSPTR gives pin state as input. - * Writing the same bits sets the output value. - * This makes regular read-modify-write difficult so we - * use sp->val to keep track of the latest register value. - */ - - if (on) - sp->val |= bits; - else - sp->val &= ~bits; - - iowrite8(sp->val, SCSPTR(sp)); -} - -static inline void setsck(struct spi_device *dev, int on) -{ - setbits(spi_master_get_devdata(dev->master), PIN_SCK, on); -} - -static inline void setmosi(struct spi_device *dev, int on) -{ - setbits(spi_master_get_devdata(dev->master), PIN_TXD, on); -} - -static inline u32 getmiso(struct spi_device *dev) -{ - struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); - - return (ioread8(SCSPTR(sp)) & PIN_RXD) ? 1 : 0; -} - -#define spidelay(x) ndelay(x) - -#include "spi-bitbang-txrx.h" - -static u32 sh_sci_spi_txrx_mode0(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits, - unsigned flags) -{ - return bitbang_txrx_be_cpha0(spi, nsecs, 0, flags, word, bits); -} - -static u32 sh_sci_spi_txrx_mode1(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits, - unsigned flags) -{ - return bitbang_txrx_be_cpha1(spi, nsecs, 0, flags, word, bits); -} - -static u32 sh_sci_spi_txrx_mode2(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits, - unsigned flags) -{ - return bitbang_txrx_be_cpha0(spi, nsecs, 1, flags, word, bits); -} - -static u32 sh_sci_spi_txrx_mode3(struct spi_device *spi, - unsigned nsecs, u32 word, u8 bits, - unsigned flags) -{ - return bitbang_txrx_be_cpha1(spi, nsecs, 1, flags, word, bits); -} - -static void sh_sci_spi_chipselect(struct spi_device *dev, int value) -{ - struct sh_sci_spi *sp = spi_master_get_devdata(dev->master); - - if (sp->info->chip_select) - (sp->info->chip_select)(sp->info, dev->chip_select, value); -} - -static int sh_sci_spi_probe(struct platform_device *dev) -{ - struct resource *r; - struct spi_master *master; - struct sh_sci_spi *sp; - int ret; - - master = spi_alloc_master(&dev->dev, sizeof(struct sh_sci_spi)); - if (master == NULL) { - dev_err(&dev->dev, "failed to allocate spi master\n"); - ret = -ENOMEM; - goto err0; - } - - sp = spi_master_get_devdata(master); - - platform_set_drvdata(dev, sp); - sp->info = dev_get_platdata(&dev->dev); - if (!sp->info) { - dev_err(&dev->dev, "platform data is missing\n"); - ret = -ENOENT; - goto err1; - } - - /* setup spi bitbang adaptor */ - sp->bitbang.master = master; - sp->bitbang.master->bus_num = sp->info->bus_num; - sp->bitbang.master->num_chipselect = sp->info->num_chipselect; - sp->bitbang.chipselect = sh_sci_spi_chipselect; - - sp->bitbang.txrx_word[SPI_MODE_0] = sh_sci_spi_txrx_mode0; - sp->bitbang.txrx_word[SPI_MODE_1] = sh_sci_spi_txrx_mode1; - sp->bitbang.txrx_word[SPI_MODE_2] = sh_sci_spi_txrx_mode2; - sp->bitbang.txrx_word[SPI_MODE_3] = sh_sci_spi_txrx_mode3; - - r = platform_get_resource(dev, IORESOURCE_MEM, 0); - if (r == NULL) { - ret = -ENOENT; - goto err1; - } - sp->membase = ioremap(r->start, resource_size(r)); - if (!sp->membase) { - ret = -ENXIO; - goto err1; - } - sp->val = ioread8(SCSPTR(sp)); - setbits(sp, PIN_INIT, 1); - - ret = spi_bitbang_start(&sp->bitbang); - if (!ret) - return 0; - - setbits(sp, PIN_INIT, 0); - iounmap(sp->membase); - err1: - spi_master_put(sp->bitbang.master); - err0: - return ret; -} - -static int sh_sci_spi_remove(struct platform_device *dev) -{ - struct sh_sci_spi *sp = platform_get_drvdata(dev); - - spi_bitbang_stop(&sp->bitbang); - setbits(sp, PIN_INIT, 0); - iounmap(sp->membase); - spi_master_put(sp->bitbang.master); - return 0; -} - -static struct platform_driver sh_sci_spi_drv = { - .probe = sh_sci_spi_probe, - .remove = sh_sci_spi_remove, - .driver = { - .name = "spi_sh_sci", - }, -}; -module_platform_driver(sh_sci_spi_drv); - -MODULE_DESCRIPTION("SH SCI SPI Driver"); -MODULE_AUTHOR("Magnus Damm "); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:spi_sh_sci"); From patchwork Fri Jan 13 06:23:38 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642269 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 06CDFC71131 for ; Fri, 13 Jan 2023 06:29:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S241254AbjAMG3k (ORCPT ); Fri, 13 Jan 2023 01:29:40 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37814 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S239506AbjAMG1K (ORCPT ); Fri, 13 Jan 2023 01:27:10 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 37D1E6B18C; Thu, 12 Jan 2023 22:25:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=zn2TAaVu38FIU65k7/MT4xLZlbVRoRB8asSaJE0SHvU=; b=fnW6I1OjxCV/+qCsEUVt/I2ltx pVazaxhtTWwOIFpuSgV6S/wrRsGO0a/JL9Td5f60CfSJn6rTXQrpT7rBZgWhpR1xWyE0Qgwb3e5Zy 4xYHJNUH36rYOUlCEJc2GhFeezJZ9AunFCAdE9DOQH7vpp7WH6nP+ijWR7nX8lLuXuyAS3ijRmg7R N/W1AmVs/dORBf3sC4X6YxUxqheUzey81JPGw+OvSRgvvpFrFD097CgP86vfGOsIcx6qaVl9TOX3v LtdFkCrdEDDEoYkoG3xniDxe0zLInwtaWTr/4pr7zm63OFXIpgGRxp+awTDCHrO/CuJ7EvBvDGGdC +Le7Nwsg==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUl-000m83-Hp; Fri, 13 Jan 2023 06:24:56 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 21/22] drivers: platform: remove is_sh_early_platform_device Date: Fri, 13 Jan 2023 07:23:38 +0100 Message-Id: <20230113062339.1909087-22-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This was used as a hack for sh-architecture device initialization, and with sh gone now, only the stub that always returns 0 is left. Signed-off-by: Christoph Hellwig --- drivers/clocksource/sh_cmt.c | 8 ++------ drivers/clocksource/sh_mtu2.c | 8 ++------ drivers/clocksource/sh_tmu.c | 9 ++------- include/linux/platform_device.h | 12 ------------ 4 files changed, 6 insertions(+), 31 deletions(-) diff --git a/drivers/clocksource/sh_cmt.c b/drivers/clocksource/sh_cmt.c index 7fed3529bbaf82..4f6d7d40c9fcb1 100644 --- a/drivers/clocksource/sh_cmt.c +++ b/drivers/clocksource/sh_cmt.c @@ -1109,10 +1109,8 @@ static int sh_cmt_probe(struct platform_device *pdev) struct sh_cmt_device *cmt = platform_get_drvdata(pdev); int ret; - if (!is_sh_early_platform_device(pdev)) { - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - } + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); if (cmt) { dev_info(&pdev->dev, "kept as earlytimer\n"); @@ -1129,8 +1127,6 @@ static int sh_cmt_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); return ret; } - if (is_sh_early_platform_device(pdev)) - return 0; out: if (cmt->has_clockevent || cmt->has_clocksource) diff --git a/drivers/clocksource/sh_mtu2.c b/drivers/clocksource/sh_mtu2.c index e81e978513f80e..97ac2929e424be 100644 --- a/drivers/clocksource/sh_mtu2.c +++ b/drivers/clocksource/sh_mtu2.c @@ -448,10 +448,8 @@ static int sh_mtu2_probe(struct platform_device *pdev) struct sh_mtu2_device *mtu = platform_get_drvdata(pdev); int ret; - if (!is_sh_early_platform_device(pdev)) { - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - } + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); if (mtu) { dev_info(&pdev->dev, "kept as earlytimer\n"); @@ -468,8 +466,6 @@ static int sh_mtu2_probe(struct platform_device *pdev) pm_runtime_idle(&pdev->dev); return ret; } - if (is_sh_early_platform_device(pdev)) - return 0; out: if (mtu->has_clockevent) diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c index 596e9146ad54e9..940378d38dd523 100644 --- a/drivers/clocksource/sh_tmu.c +++ b/drivers/clocksource/sh_tmu.c @@ -595,10 +595,8 @@ static int sh_tmu_probe(struct platform_device *pdev) struct sh_tmu_device *tmu = platform_get_drvdata(pdev); int ret; - if (!is_sh_early_platform_device(pdev)) { - pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); - } + pm_runtime_set_active(&pdev->dev); + pm_runtime_enable(&pdev->dev); if (tmu) { dev_info(&pdev->dev, "kept as earlytimer\n"); @@ -616,9 +614,6 @@ static int sh_tmu_probe(struct platform_device *pdev) return ret; } - if (is_sh_early_platform_device(pdev)) - return 0; - out: if (tmu->has_clockevent || tmu->has_clocksource) pm_runtime_irq_safe(&pdev->dev); diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index b0d5a253156ece..894939a74dd20f 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -352,18 +352,6 @@ extern int platform_pm_restore(struct device *dev); #define USE_PLATFORM_PM_SLEEP_OPS #endif -#ifndef CONFIG_SUPERH -/* - * REVISIT: This stub is needed for all non-SuperH users of early platform - * drivers. It should go away once we introduce the new platform_device-based - * early driver framework. - */ -static inline int is_sh_early_platform_device(struct platform_device *pdev) -{ - return 0; -} -#endif /* CONFIG_SUPERH */ - /* For now only SuperH uses it */ void early_platform_cleanup(void); From patchwork Fri Jan 13 06:23:39 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christoph Hellwig X-Patchwork-Id: 642267 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id BD182C54EBD for ; Fri, 13 Jan 2023 06:29:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S240845AbjAMG3w (ORCPT ); Fri, 13 Jan 2023 01:29:52 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:37912 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S240857AbjAMG1P (ORCPT ); Fri, 13 Jan 2023 01:27:15 -0500 Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id CA4926B19F; Thu, 12 Jan 2023 22:25:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: MIME-Version:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From:Sender :Reply-To:Content-Type:Content-ID:Content-Description; bh=V1vQGE3XW96qQp3ejFsm70w3mnOS9+pWBLCZirkv1tk=; b=2+SiOyCvTzvDZZCeuwWrAYwhzj EWAQESOIDtQymDuYM0T7JpVes3xvB7NFWQ+KmJV1uAOpOiRJUBjTMIMZUpzF2ix6MOt0hGo62CWng diwLKN81u+WjRqFmLkwMZ873sIws+XMLCIUxrN4I7r+ZaeFve8swojZ2Nb8EGuKmlXeIEB1nRyph2 AGmxrxbCZm5edKIVp4yRI47qeIEa85kNn0gl7iBuYuEaOtP2HtGe1Lkv6xia/XchQLm3DtxOaVah4 5sBY0LpYQziGvInjmbVYYVxDsXL3Jm0yMz0PJd+Su5dRSgTKQwyncOI0wCWZmAu3ILcI2jS/gxiK0 qG4NqsbA==; Received: from [2001:4bb8:181:656b:9509:7d20:8d39:f895] (helo=localhost) by bombadil.infradead.org with esmtpsa (Exim 4.94.2 #2 (Red Hat Linux)) id 1pGDUo-000m9z-Df; Fri, 13 Jan 2023 06:24:59 +0000 From: Christoph Hellwig To: Yoshinori Sato , Rich Felker , Arnd Bergmann , Greg Kroah-Hartman Cc: Laurent Pinchart , Kieran Bingham , Geert Uytterhoeven , linux-kernel@vger.kernel.org, linux-watchdog@vger.kernel.org, devicetree@vger.kernel.org, linux-arch@vger.kernel.org, dmaengine@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-renesas-soc@vger.kernel.org, linux-i2c@vger.kernel.org, linux-input@vger.kernel.org, linux-media@vger.kernel.org, linux-mmc@vger.kernel.org, linux-mtd@lists.infradead.org, netdev@vger.kernel.org, linux-gpio@vger.kernel.org, linux-rtc@vger.kernel.org, linux-spi@vger.kernel.org, linux-serial@vger.kernel.org, linux-usb@vger.kernel.org, linux-fbdev@vger.kernel.org, alsa-devel@alsa-project.org, linux-sh@vger.kernel.org Subject: [PATCH 22/22] drivers: platform: remove early_platform_cleanup Date: Fri, 13 Jan 2023 07:23:39 +0100 Message-Id: <20230113062339.1909087-23-hch@lst.de> X-Mailer: git-send-email 2.39.0 In-Reply-To: <20230113062339.1909087-1-hch@lst.de> References: <20230113062339.1909087-1-hch@lst.de> MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by bombadil.infradead.org. See http://www.infradead.org/rpr.html Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This weak stub was only overriden by the now remove sh architecture. Signed-off-by: Christoph Hellwig --- drivers/base/platform.c | 4 ---- include/linux/platform_device.h | 3 --- 2 files changed, 7 deletions(-) diff --git a/drivers/base/platform.c b/drivers/base/platform.c index 968f3d71eeab2e..eb3feabf6c2f53 100644 --- a/drivers/base/platform.c +++ b/drivers/base/platform.c @@ -1506,14 +1506,10 @@ struct device *platform_find_device_by_driver(struct device *start, } EXPORT_SYMBOL_GPL(platform_find_device_by_driver); -void __weak __init early_platform_cleanup(void) { } - int __init platform_bus_init(void) { int error; - early_platform_cleanup(); - error = device_register(&platform_bus); if (error) { put_device(&platform_bus); diff --git a/include/linux/platform_device.h b/include/linux/platform_device.h index 894939a74dd20f..86692f730e3a12 100644 --- a/include/linux/platform_device.h +++ b/include/linux/platform_device.h @@ -352,7 +352,4 @@ extern int platform_pm_restore(struct device *dev); #define USE_PLATFORM_PM_SLEEP_OPS #endif -/* For now only SuperH uses it */ -void early_platform_cleanup(void); - #endif /* _PLATFORM_DEVICE_H_ */