summaryrefslogtreecommitdiff
path: root/arch/sh/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'arch/sh/drivers')
-rw-r--r--arch/sh/drivers/Kconfig1
-rw-r--r--arch/sh/drivers/Makefile4
-rw-r--r--arch/sh/drivers/dma/Kconfig23
-rw-r--r--arch/sh/drivers/dma/Makefile1
-rw-r--r--arch/sh/drivers/dma/dma-api.c166
-rw-r--r--arch/sh/drivers/dma/dma-g2.c7
-rw-r--r--arch/sh/drivers/dma/dma-pvr2.c16
-rw-r--r--arch/sh/drivers/dma/dma-sh.c46
-rw-r--r--arch/sh/drivers/dma/dma-sysfs.c15
-rw-r--r--arch/sh/drivers/dma/dmabrg.c5
-rw-r--r--arch/sh/drivers/heartbeat.c46
-rw-r--r--arch/sh/drivers/pci/Makefile3
-rw-r--r--arch/sh/drivers/pci/common.c38
-rw-r--r--arch/sh/drivers/pci/fixups-cayman.c77
-rw-r--r--arch/sh/drivers/pci/fixups-dreamcast.c31
-rw-r--r--arch/sh/drivers/pci/fixups-landisk.c4
-rw-r--r--arch/sh/drivers/pci/fixups-r7780rp.c7
-rw-r--r--arch/sh/drivers/pci/fixups-rts7751r2d.c11
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7780.c9
-rw-r--r--arch/sh/drivers/pci/fixups-sdk7786.c7
-rw-r--r--arch/sh/drivers/pci/fixups-se7751.c3
-rw-r--r--arch/sh/drivers/pci/fixups-sh03.c3
-rw-r--r--arch/sh/drivers/pci/fixups-snapgear.c6
-rw-r--r--arch/sh/drivers/pci/fixups-titan.c8
-rw-r--r--arch/sh/drivers/pci/ops-dreamcast.c5
-rw-r--r--arch/sh/drivers/pci/ops-sh4.c5
-rw-r--r--arch/sh/drivers/pci/ops-sh5.c68
-rw-r--r--arch/sh/drivers/pci/ops-sh7786.c5
-rw-r--r--arch/sh/drivers/pci/pci-dreamcast.c5
-rw-r--r--arch/sh/drivers/pci/pci-sh4.h9
-rw-r--r--arch/sh/drivers/pci/pci-sh5.c220
-rw-r--r--arch/sh/drivers/pci/pci-sh5.h110
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.c7
-rw-r--r--arch/sh/drivers/pci/pci-sh7751.h7
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.c30
-rw-r--r--arch/sh/drivers/pci/pci-sh7780.h7
-rw-r--r--arch/sh/drivers/pci/pci.c113
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.c103
-rw-r--r--arch/sh/drivers/pci/pcie-sh7786.h10
-rw-r--r--arch/sh/drivers/platform_early.c340
-rw-r--r--arch/sh/drivers/push-switch.c23
-rw-r--r--arch/sh/drivers/superhyway/Makefile6
-rw-r--r--arch/sh/drivers/superhyway/ops-sh4-202.c171
43 files changed, 617 insertions, 1164 deletions
diff --git a/arch/sh/drivers/Kconfig b/arch/sh/drivers/Kconfig
index 420c6b2f33a5..80a45ad2852f 100644
--- a/arch/sh/drivers/Kconfig
+++ b/arch/sh/drivers/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
source "arch/sh/drivers/dma/Kconfig"
source "arch/sh/cchips/Kconfig"
diff --git a/arch/sh/drivers/Makefile b/arch/sh/drivers/Makefile
index e13f06bebd92..8bd10b904bf9 100644
--- a/arch/sh/drivers/Makefile
+++ b/arch/sh/drivers/Makefile
@@ -1,10 +1,10 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the Linux SuperH-specific device drivers.
#
-obj-y += dma/
+obj-y += dma/ platform_early.o
obj-$(CONFIG_PCI) += pci/
-obj-$(CONFIG_SUPERHYWAY) += superhyway/
obj-$(CONFIG_PUSH_SWITCH) += push-switch.o
obj-$(CONFIG_HEARTBEAT) += heartbeat.o
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig
index cfd5b90a8628..08d937a6d249 100644
--- a/arch/sh/drivers/dma/Kconfig
+++ b/arch/sh/drivers/dma/Kconfig
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
menu "DMA support"
@@ -12,9 +13,8 @@ config SH_DMA_IRQ_MULTI
default y if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7750R || \
CPU_SUBTYPE_SH7751R || CPU_SUBTYPE_SH7091 || \
- CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7764 || \
- CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785 || \
- CPU_SUBTYPE_SH7760
+ CPU_SUBTYPE_SH7763 || CPU_SUBTYPE_SH7780 || \
+ CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7760
config SH_DMA_API
depends on SH_DMA
@@ -28,17 +28,19 @@ config SH_DMA_API
config NR_ONCHIP_DMA_CHANNELS
int
depends on SH_DMA
- default "4" if CPU_SUBTYPE_SH7750 || CPU_SUBTYPE_SH7751 || \
- CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7091
+ default "4" if CPU_SUBTYPE_SH7709 || CPU_SUBTYPE_SH7750 || \
+ CPU_SUBTYPE_SH7750S || CPU_SUBTYPE_SH7751 || \
+ CPU_SUBTYPE_SH7091
default "8" if CPU_SUBTYPE_SH7750R || CPU_SUBTYPE_SH7751R || \
CPU_SUBTYPE_SH7760
- default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7780 || \
- CPU_SUBTYPE_SH7785 || CPU_SUBTYPE_SH7724
+ default "12" if CPU_SUBTYPE_SH7723 || CPU_SUBTYPE_SH7724 || \
+ CPU_SUBTYPE_SH7780 || CPU_SUBTYPE_SH7785
default "6"
help
This allows you to specify the number of channels that the on-chip
- DMAC supports. This will be 4 for SH7750/SH7751/Sh7750S/SH7091 and 8 for the
- SH7750R/SH7751R/SH7760, 12 for the SH7723/SH7780/SH7785/SH7724, default is 6.
+ DMAC supports. This will be 4 for SH7709/SH7750/SH7750S/SH7751/SH7091,
+ 8 for SH7750R/SH7751R/SH7760, and 12 for SH7723/SH7724/SH7780/SH7785.
+ Default is 6.
config SH_DMABRG
bool "SH7760 DMABRG support"
@@ -63,8 +65,7 @@ config PVR2_DMA
config G2_DMA
tristate "G2 Bus DMA support"
- depends on SH_DREAMCAST
- select SH_DMA_API
+ depends on SH_DREAMCAST && SH_DMA_API
help
This enables support for the DMA controller for the Dreamcast's
G2 bus. Drivers that want this will generally enable this on
diff --git a/arch/sh/drivers/dma/Makefile b/arch/sh/drivers/dma/Makefile
index d88c9484762c..d2fdd56208f6 100644
--- a/arch/sh/drivers/dma/Makefile
+++ b/arch/sh/drivers/dma/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the SuperH DMA specific kernel interface routines under Linux.
#
diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c
index c0eec08d8f95..87e5a8928873 100644
--- a/arch/sh/drivers/dma/dma-api.c
+++ b/arch/sh/drivers/dma/dma-api.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/dma/dma-api.c
*
* SuperH-specific DMA management API
*
* Copyright (C) 2003, 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 <linux/init.h>
#include <linux/module.h>
@@ -44,21 +41,6 @@ struct dma_info *get_dma_info(unsigned int chan)
}
EXPORT_SYMBOL(get_dma_info);
-struct dma_info *get_dma_info_by_name(const char *dmac_name)
-{
- struct dma_info *info;
-
- list_for_each_entry(info, &registered_dmac_list, list) {
- if (dmac_name && (strcmp(dmac_name, info->name) != 0))
- continue;
- else
- return info;
- }
-
- return NULL;
-}
-EXPORT_SYMBOL(get_dma_info_by_name);
-
static unsigned int get_nr_channels(void)
{
struct dma_info *info;
@@ -104,93 +86,6 @@ int get_dma_residue(unsigned int chan)
}
EXPORT_SYMBOL(get_dma_residue);
-static int search_cap(const char **haystack, const char *needle)
-{
- const char **p;
-
- for (p = haystack; *p; p++)
- if (strcmp(*p, needle) == 0)
- return 1;
-
- return 0;
-}
-
-/**
- * request_dma_bycap - Allocate a DMA channel based on its capabilities
- * @dmac: List of DMA controllers to search
- * @caps: List of capabilities
- *
- * Search all channels of all DMA controllers to find a channel which
- * matches the requested capabilities. The result is the channel
- * number if a match is found, or %-ENODEV if no match is found.
- *
- * Note that not all DMA controllers export capabilities, in which
- * case they can never be allocated using this API, and so
- * request_dma() must be used specifying the channel number.
- */
-int request_dma_bycap(const char **dmac, const char **caps, const char *dev_id)
-{
- unsigned int found = 0;
- struct dma_info *info;
- const char **p;
- int i;
-
- BUG_ON(!dmac || !caps);
-
- list_for_each_entry(info, &registered_dmac_list, list)
- if (strcmp(*dmac, info->name) == 0) {
- found = 1;
- break;
- }
-
- if (!found)
- return -ENODEV;
-
- for (i = 0; i < info->nr_channels; i++) {
- struct dma_channel *channel = &info->channels[i];
-
- if (unlikely(!channel->caps))
- continue;
-
- for (p = caps; *p; p++) {
- if (!search_cap(channel->caps, *p))
- break;
- if (request_dma(channel->chan, dev_id) == 0)
- return channel->chan;
- }
- }
-
- return -EINVAL;
-}
-EXPORT_SYMBOL(request_dma_bycap);
-
-int dmac_search_free_channel(const char *dev_id)
-{
- struct dma_channel *channel = { 0 };
- struct dma_info *info = get_dma_info(0);
- int i;
-
- for (i = 0; i < info->nr_channels; i++) {
- channel = &info->channels[i];
- if (unlikely(!channel))
- return -ENODEV;
-
- if (atomic_read(&channel->busy) == 0)
- break;
- }
-
- if (info->ops->request) {
- int result = info->ops->request(channel);
- if (result)
- return result;
-
- atomic_set(&channel->busy, 1);
- return channel->chan;
- }
-
- return -ENOSYS;
-}
-
int request_dma(unsigned int chan, const char *dev_id)
{
struct dma_channel *channel = { 0 };
@@ -201,7 +96,7 @@ int request_dma(unsigned int chan, const char *dev_id)
if (atomic_xchg(&channel->busy, 1))
return -EBUSY;
- strlcpy(channel->dev_id, dev_id, sizeof(channel->dev_id));
+ strscpy(channel->dev_id, dev_id, sizeof(channel->dev_id));
if (info->ops->request) {
result = info->ops->request(channel);
@@ -243,35 +138,6 @@ void dma_wait_for_completion(unsigned int chan)
}
EXPORT_SYMBOL(dma_wait_for_completion);
-int register_chan_caps(const char *dmac, struct dma_chan_caps *caps)
-{
- struct dma_info *info;
- unsigned int found = 0;
- int i;
-
- list_for_each_entry(info, &registered_dmac_list, list)
- if (strcmp(dmac, info->name) == 0) {
- found = 1;
- break;
- }
-
- if (unlikely(!found))
- return -ENODEV;
-
- for (i = 0; i < info->nr_channels; i++, caps++) {
- struct dma_channel *channel;
-
- if ((info->first_channel_nr + i) != caps->ch_num)
- return -EINVAL;
-
- channel = &info->channels[i];
- channel->caps = caps->caplist;
- }
-
- return 0;
-}
-EXPORT_SYMBOL(register_chan_caps);
-
void dma_configure_channel(unsigned int chan, unsigned long flags)
{
struct dma_info *info = get_dma_info(chan);
@@ -297,18 +163,6 @@ int dma_xfer(unsigned int chan, unsigned long from,
}
EXPORT_SYMBOL(dma_xfer);
-int dma_extend(unsigned int chan, unsigned long op, void *param)
-{
- struct dma_info *info = get_dma_info(chan);
- struct dma_channel *channel = get_dma_channel(chan);
-
- if (info->ops->extend)
- return info->ops->extend(channel, op, param);
-
- return -ENOSYS;
-}
-EXPORT_SYMBOL(dma_extend);
-
static int dma_proc_show(struct seq_file *m, void *v)
{
struct dma_info *info = v;
@@ -339,18 +193,6 @@ static int dma_proc_show(struct seq_file *m, void *v)
return 0;
}
-static int dma_proc_open(struct inode *inode, struct file *file)
-{
- return single_open(file, dma_proc_show, NULL);
-}
-
-static const struct file_operations dma_proc_fops = {
- .open = dma_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
int register_dmac(struct dma_info *info)
{
unsigned int total_channels, i;
@@ -423,10 +265,10 @@ EXPORT_SYMBOL(unregister_dmac);
static int __init dma_api_init(void)
{
printk(KERN_NOTICE "DMA: Registering DMA API.\n");
- return proc_create("dma", 0, NULL, &dma_proc_fops) ? 0 : -ENOMEM;
+ return proc_create_single("dma", 0, NULL, dma_proc_show) ? 0 : -ENOMEM;
}
subsys_initcall(dma_api_init);
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
MODULE_DESCRIPTION("DMA API for SuperH");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c
index e1ab6eb3c04b..52a8ae5e30d2 100644
--- a/arch/sh/drivers/dma/dma-g2.c
+++ b/arch/sh/drivers/dma/dma-g2.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/dma/dma-g2.c
*
* G2 bus DMA support
*
* Copyright (C) 2003 - 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.
*/
#include <linux/init.h>
#include <linux/kernel.h>
@@ -197,4 +194,4 @@ module_exit(g2_dma_exit);
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
MODULE_DESCRIPTION("G2 bus DMA driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c
index 706a3434af7a..21c347543e19 100644
--- a/arch/sh/drivers/dma/dma-pvr2.c
+++ b/arch/sh/drivers/dma/dma-pvr2.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/dma/dma-pvr2.c
*
* NEC PowerVR 2 (Dreamcast) DMA support
*
* Copyright (C) 2003, 2004 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 <linux/init.h>
#include <linux/kernel.h>
@@ -67,11 +64,6 @@ static int pvr2_xfer_dma(struct dma_channel *chan)
return 0;
}
-static struct irqaction pvr2_dma_irq = {
- .name = "pvr2 DMA handler",
- .handler = pvr2_dma_interrupt,
-};
-
static struct dma_ops pvr2_dma_ops = {
.request = pvr2_request_dma,
.get_residue = pvr2_get_dma_residue,
@@ -87,7 +79,9 @@ static struct dma_info pvr2_dma_info = {
static int __init pvr2_dma_init(void)
{
- setup_irq(HW_EVENT_PVR2_DMA, &pvr2_dma_irq);
+ if (request_irq(HW_EVENT_PVR2_DMA, pvr2_dma_interrupt, 0,
+ "pvr2 DMA handler", NULL))
+ pr_err("Failed to register pvr2 DMA handler interrupt\n");
request_dma(PVR2_CASCADE_CHAN, "pvr2 cascade");
return register_dmac(&pvr2_dma_info);
@@ -105,4 +99,4 @@ module_exit(pvr2_dma_exit);
MODULE_AUTHOR("Paul Mundt <lethal@linux-sh.org>");
MODULE_DESCRIPTION("NEC PowerVR 2 DMA driver");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c
index b22565623142..306fba1564e5 100644
--- a/arch/sh/drivers/dma/dma-sh.c
+++ b/arch/sh/drivers/dma/dma-sh.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/dma/dma-sh.c
*
@@ -6,10 +7,6 @@
* Copyright (C) 2000 Takashi YOSHII
* Copyright (C) 2003, 2004 Paul Mundt
* Copyright (C) 2005 Andriy Skulysh
- *
- * 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 <linux/init.h>
#include <linux/interrupt.h>
@@ -22,17 +19,29 @@
#include <cpu/dma.h>
/*
+ * Some of the SoCs feature two DMAC modules. In such a case, the channels are
+ * distributed equally among them.
+ */
+#ifdef SH_DMAC_BASE1
+#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2)
+#else
+#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS
+#endif
+
+#define SH_DMAC_CH_SZ 0x10
+
+/*
* Define the default configuration for dual address memory-memory transfer.
* The 0x400 value represents auto-request, external->external.
*/
-#define RS_DUAL (DM_INC | SM_INC | 0x400 | TS_INDEX2VAL(XMIT_SZ_32BIT))
+#define RS_DUAL (DM_INC | SM_INC | RS_AUTO | TS_INDEX2VAL(XMIT_SZ_32BIT))
static unsigned long dma_find_base(unsigned int chan)
{
unsigned long base = SH_DMAC_BASE0;
#ifdef SH_DMAC_BASE1
- if (chan >= 6)
+ if (chan >= SH_DMAC_NR_MD_CH)
base = SH_DMAC_BASE1;
#endif
@@ -43,13 +52,13 @@ static unsigned long dma_base_addr(unsigned int chan)
{
unsigned long base = dma_find_base(chan);
- /* Normalize offset calculation */
- if (chan >= 9)
- chan -= 6;
- if (chan >= 4)
- base += 0x10;
+ chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ;
+
+ /* DMAOR is placed inside the channel register space. Step over it. */
+ if (chan >= DMAOR)
+ base += SH_DMAC_CH_SZ;
- return base + (chan * 0x10);
+ return base + chan;
}
#ifdef CONFIG_SH_DMA_IRQ_MULTI
@@ -253,12 +262,11 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan)
#define NR_DMAOR 1
#endif
-/*
- * DMAOR bases are broken out amongst channel groups. DMAOR0 manages
- * channels 0 - 5, DMAOR1 6 - 11 (optional).
- */
-#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6))
-#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6)
+#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \
+ SH_DMAC_NR_MD_CH) + DMAOR)
+#define dmaor_write_reg(n, data) __raw_writew(data, \
+ dma_find_base((n) * \
+ SH_DMAC_NR_MD_CH) + DMAOR)
static inline int dmaor_reset(int no)
{
@@ -414,4 +422,4 @@ module_exit(sh_dmac_exit);
MODULE_AUTHOR("Takashi YOSHII, Paul Mundt, Andriy Skulysh");
MODULE_DESCRIPTION("SuperH On-Chip DMAC Support");
-MODULE_LICENSE("GPL");
+MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c
index 4b15feda54b0..9f666280d80c 100644
--- a/arch/sh/drivers/dma/dma-sysfs.c
+++ b/arch/sh/drivers/dma/dma-sysfs.c
@@ -1,13 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/dma/dma-sysfs.c
*
* sysfs interface for SH DMA API
*
* Copyright (C) 2004 - 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.
*/
#include <linux/kernel.h>
#include <linux/init.h>
@@ -18,7 +15,7 @@
#include <linux/string.h>
#include <asm/dma.h>
-static struct bus_type dma_subsys = {
+static const struct bus_type dma_subsys = {
.name = "dma",
.dev_name = "dma",
};
@@ -48,13 +45,19 @@ static DEVICE_ATTR(devices, S_IRUGO, dma_show_devices, NULL);
static int __init dma_subsys_init(void)
{
+ struct device *dev_root;
int ret;
ret = subsys_system_register(&dma_subsys, NULL);
if (unlikely(ret))
return ret;
- return device_create_file(dma_subsys.dev_root, &dev_attr_devices);
+ dev_root = bus_get_dev_root(&dma_subsys);
+ if (dev_root) {
+ ret = device_create_file(dev_root, &dev_attr_devices);
+ put_device(dev_root);
+ }
+ return ret;
}
postcore_initcall(dma_subsys_init);
diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c
index c0dd904483c7..5b2c1fd254d7 100644
--- a/arch/sh/drivers/dma/dmabrg.c
+++ b/arch/sh/drivers/dma/dmabrg.c
@@ -1,9 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* SH7760 DMABRG IRQ handling
*
* (c) 2007 MSC Vertriebsges.m.b.H, Manuel Lauss <mlau@msc-ge.com>
- * licensed under the GPLv2.
- *
*/
#include <linux/interrupt.h>
@@ -154,7 +153,7 @@ static int __init dmabrg_init(void)
unsigned long or;
int ret;
- dmabrg_handlers = kzalloc(10 * sizeof(struct dmabrg_handler),
+ dmabrg_handlers = kcalloc(10, sizeof(struct dmabrg_handler),
GFP_KERNEL);
if (!dmabrg_handlers)
return -ENOMEM;
diff --git a/arch/sh/drivers/heartbeat.c b/arch/sh/drivers/heartbeat.c
index 7efc9c354fc7..42103038a7d0 100644
--- a/arch/sh/drivers/heartbeat.c
+++ b/arch/sh/drivers/heartbeat.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Generic heartbeat driver for regular LED banks
*
@@ -13,15 +14,11 @@
* traditionally used for strobing the load average. This use case is
* handled by this driver, rather than giving each LED bit position its
* own struct device.
- *
- * 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 <linux/init.h>
-#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/sched.h>
+#include <linux/sched/loadavg.h>
#include <linux/timer.h>
#include <linux/io.h>
#include <linux/slab.h>
@@ -59,9 +56,9 @@ static inline void heartbeat_toggle_bit(struct heartbeat_data *hd,
}
}
-static void heartbeat_timer(unsigned long data)
+static void heartbeat_timer(struct timer_list *t)
{
- struct heartbeat_data *hd = (struct heartbeat_data *)data;
+ struct heartbeat_data *hd = timer_container_of(hd, t, timer);
static unsigned bit = 0, up = 1;
heartbeat_toggle_bit(hd, bit, hd->flags & HEARTBEAT_INVERTED);
@@ -99,7 +96,7 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
return -ENOMEM;
}
- hd->base = ioremap_nocache(res->start, resource_size(res));
+ hd->base = ioremap(res->start, resource_size(res));
if (unlikely(!hd->base)) {
dev_err(&pdev->dev, "ioremap failed\n");
@@ -133,32 +130,17 @@ static int heartbeat_drv_probe(struct platform_device *pdev)
}
}
- setup_timer(&hd->timer, heartbeat_timer, (unsigned long)hd);
+ timer_setup(&hd->timer, heartbeat_timer, 0);
platform_set_drvdata(pdev, hd);
return mod_timer(&hd->timer, jiffies + 1);
}
-static int heartbeat_drv_remove(struct platform_device *pdev)
-{
- struct heartbeat_data *hd = platform_get_drvdata(pdev);
-
- del_timer_sync(&hd->timer);
- iounmap(hd->base);
-
- platform_set_drvdata(pdev, NULL);
-
- if (!pdev->dev.platform_data)
- kfree(hd);
-
- return 0;
-}
-
static struct platform_driver heartbeat_driver = {
.probe = heartbeat_drv_probe,
- .remove = heartbeat_drv_remove,
.driver = {
- .name = DRV_NAME,
+ .name = DRV_NAME,
+ .suppress_bind_attrs = true,
},
};
@@ -167,14 +149,4 @@ static int __init heartbeat_init(void)
printk(KERN_NOTICE DRV_NAME ": version %s loaded\n", DRV_VERSION);
return platform_driver_register(&heartbeat_driver);
}
-
-static void __exit heartbeat_exit(void)
-{
- platform_driver_unregister(&heartbeat_driver);
-}
-module_init(heartbeat_init);
-module_exit(heartbeat_exit);
-
-MODULE_VERSION(DRV_VERSION);
-MODULE_AUTHOR("Paul Mundt");
-MODULE_LICENSE("GPL v2");
+device_initcall(heartbeat_init);
diff --git a/arch/sh/drivers/pci/Makefile b/arch/sh/drivers/pci/Makefile
index 82f0a335fd19..d313fd3ce709 100644
--- a/arch/sh/drivers/pci/Makefile
+++ b/arch/sh/drivers/pci/Makefile
@@ -1,3 +1,4 @@
+# SPDX-License-Identifier: GPL-2.0
#
# Makefile for the PCI specific kernel interface routines under Linux.
#
@@ -9,7 +10,6 @@ obj-$(CONFIG_CPU_SUBTYPE_SH7763) += pci-sh7780.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7780) += pci-sh7780.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7785) += pci-sh7780.o ops-sh4.o
obj-$(CONFIG_CPU_SUBTYPE_SH7786) += pcie-sh7786.o ops-sh7786.o
-obj-$(CONFIG_CPU_SH5) += pci-sh5.o ops-sh5.o
obj-$(CONFIG_SH_DREAMCAST) += ops-dreamcast.o fixups-dreamcast.o \
pci-dreamcast.o
@@ -25,4 +25,3 @@ obj-$(CONFIG_SH_7780_SOLUTION_ENGINE) += fixups-sdk7780.o
obj-$(CONFIG_SH_TITAN) += fixups-titan.o
obj-$(CONFIG_SH_LANDISK) += fixups-landisk.o
obj-$(CONFIG_SH_LBOX_RE2) += fixups-rts7751r2d.o
-obj-$(CONFIG_SH_CAYMAN) += fixups-cayman.o
diff --git a/arch/sh/drivers/pci/common.c b/arch/sh/drivers/pci/common.c
index dbf138199871..9633b6147a05 100644
--- a/arch/sh/drivers/pci/common.c
+++ b/arch/sh/drivers/pci/common.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/pci.h>
#include <linux/interrupt.h>
#include <linux/timer.h>
@@ -49,20 +50,21 @@ int __init pci_is_66mhz_capable(struct pci_channel *hose,
int top_bus, int current_bus)
{
u32 pci_devfn;
- unsigned short vid;
+ u16 vid;
int cap66 = -1;
u16 stat;
+ int ret;
- printk(KERN_INFO "PCI: Checking 66MHz capabilities...\n");
+ pr_info("PCI: Checking 66MHz capabilities...\n");
for (pci_devfn = 0; pci_devfn < 0xff; pci_devfn++) {
if (PCI_FUNC(pci_devfn))
continue;
- if (early_read_config_word(hose, top_bus, current_bus,
- pci_devfn, PCI_VENDOR_ID, &vid) !=
- PCIBIOS_SUCCESSFUL)
+ ret = early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_VENDOR_ID, &vid);
+ if (ret != PCIBIOS_SUCCESSFUL)
continue;
- if (vid == 0xffff)
+ if (PCI_POSSIBLE_ERROR(vid))
continue;
/* check 66MHz capability */
@@ -84,20 +86,20 @@ int __init pci_is_66mhz_capable(struct pci_channel *hose,
return cap66 > 0;
}
-static void pcibios_enable_err(unsigned long __data)
+static void pcibios_enable_err(struct timer_list *t)
{
- struct pci_channel *hose = (struct pci_channel *)__data;
+ struct pci_channel *hose = timer_container_of(hose, t, err_timer);
- del_timer(&hose->err_timer);
+ timer_delete(&hose->err_timer);
printk(KERN_DEBUG "PCI: re-enabling error IRQ.\n");
enable_irq(hose->err_irq);
}
-static void pcibios_enable_serr(unsigned long __data)
+static void pcibios_enable_serr(struct timer_list *t)
{
- struct pci_channel *hose = (struct pci_channel *)__data;
+ struct pci_channel *hose = timer_container_of(hose, t, serr_timer);
- del_timer(&hose->serr_timer);
+ timer_delete(&hose->serr_timer);
printk(KERN_DEBUG "PCI: re-enabling system error IRQ.\n");
enable_irq(hose->serr_irq);
}
@@ -105,15 +107,11 @@ static void pcibios_enable_serr(unsigned long __data)
void pcibios_enable_timers(struct pci_channel *hose)
{
if (hose->err_irq) {
- init_timer(&hose->err_timer);
- hose->err_timer.data = (unsigned long)hose;
- hose->err_timer.function = pcibios_enable_err;
+ timer_setup(&hose->err_timer, pcibios_enable_err, 0);
}
if (hose->serr_irq) {
- init_timer(&hose->serr_timer);
- hose->serr_timer.data = (unsigned long)hose;
- hose->serr_timer.function = pcibios_enable_serr;
+ timer_setup(&hose->serr_timer, pcibios_enable_serr, 0);
}
}
@@ -137,7 +135,7 @@ unsigned int pcibios_handle_status_errors(unsigned long addr,
pcibios_report_status(PCI_STATUS_REC_TARGET_ABORT |
PCI_STATUS_SIG_TARGET_ABORT |
PCI_STATUS_REC_MASTER_ABORT, 1);
- printk("\n");
+ pr_cont("\n");
cmd |= PCI_STATUS_REC_TARGET_ABORT;
}
@@ -146,7 +144,7 @@ unsigned int pcibios_handle_status_errors(unsigned long addr,
printk(KERN_DEBUG "PCI: parity error detected: ");
pcibios_report_status(PCI_STATUS_PARITY |
PCI_STATUS_DETECTED_PARITY, 1);
- printk("\n");
+ pr_cont("\n");
cmd |= PCI_STATUS_PARITY | PCI_STATUS_DETECTED_PARITY;
diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c
deleted file mode 100644
index edc2fb7a5bb2..000000000000
--- a/arch/sh/drivers/pci/fixups-cayman.c
+++ /dev/null
@@ -1,77 +0,0 @@
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/types.h>
-#include <cpu/irq.h>
-#include "pci-sh5.h"
-
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
- int result = -1;
-
- /* The complication here is that the PCI IRQ lines from the Cayman's 2
- 5V slots get into the CPU via a different path from the IRQ lines
- from the 3 3.3V slots. Thus, we have to detect whether the card's
- interrupts go via the 5V or 3.3V path, i.e. the 'bridge swizzling'
- at the point where we cross from 5V to 3.3V is not the normal case.
-
- The added complication is that we don't know that the 5V slots are
- always bus 2, because a card containing a PCI-PCI bridge may be
- plugged into a 3.3V slot, and this changes the bus numbering.
-
- Also, the Cayman has an intermediate PCI bus that goes a custom
- expansion board header (and to the secondary bridge). This bus has
- never been used in practice.
-
- The 1ary onboard PCI-PCI bridge is device 3 on bus 0
- The 2ary onboard PCI-PCI bridge is device 0 on the 2ary bus of
- the 1ary bridge.
- */
-
- struct slot_pin {
- int slot;
- int pin;
- } path[4];
- int i=0;
-
- while (dev->bus->number > 0) {
-
- slot = path[i].slot = PCI_SLOT(dev->devfn);
- pin = path[i].pin = pci_swizzle_interrupt_pin(dev, pin);
- dev = dev->bus->self;
- i++;
- if (i > 3) panic("PCI path to root bus too long!\n");
- }
-
- slot = PCI_SLOT(dev->devfn);
- /* This is the slot on bus 0 through which the device is eventually
- reachable. */
-
- /* Now work back up. */
- if ((slot < 3) || (i == 0)) {
- /* Bus 0 (incl. PCI-PCI bridge itself) : perform the final
- swizzle now. */
- result = IRQ_INTA + pci_swizzle_interrupt_pin(dev, pin) - 1;
- } else {
- i--;
- slot = path[i].slot;
- pin = path[i].pin;
- if (slot > 0) {
- panic("PCI expansion bus device found - not handled!\n");
- } else {
- if (i > 0) {
- /* 5V slots */
- i--;
- slot = path[i].slot;
- pin = path[i].pin;
- /* 'pin' was swizzled earlier wrt slot, don't do it again. */
- result = IRQ_P2INTA + (pin - 1);
- } else {
- /* IRQ for 2ary PCI-PCI bridge : unused */
- result = -1;
- }
- }
- }
-
- return result;
-}
diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c
index d6cde700e316..41e4daee8f04 100644
--- a/arch/sh/drivers/pci/fixups-dreamcast.c
+++ b/arch/sh/drivers/pci/fixups-dreamcast.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/pci/fixups-dreamcast.c
*
@@ -9,10 +10,6 @@
* This file originally bore the message (with enclosed-$):
* Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
* Dreamcast PCI: Supports SEGA Broadband Adaptor only.
- *
- * 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 <linux/sched.h>
@@ -22,7 +19,7 @@
#include <linux/init.h>
#include <linux/irq.h>
#include <linux/pci.h>
-#include <linux/dma-mapping.h>
+#include <linux/dma-map-ops.h>
#include <asm/io.h>
#include <asm/irq.h>
@@ -31,6 +28,8 @@
static void gapspci_fixup_resources(struct pci_dev *dev)
{
struct pci_channel *p = dev->sysdata;
+ struct resource res;
+ struct pci_bus_region region;
printk(KERN_NOTICE "PCI: Fixing up device %s\n", pci_name(dev));
@@ -50,13 +49,21 @@ static void gapspci_fixup_resources(struct pci_dev *dev)
/*
* Redirect dma memory allocations to special memory window.
+ *
+ * If this GAPSPCI region were mapped by a BAR, the CPU
+ * phys_addr_t would be pci_resource_start(), and the bus
+ * address would be pci_bus_address(pci_resource_start()).
+ * But apparently there's no BAR mapping it, so we just
+ * "know" its CPU address is GAPSPCI_DMA_BASE.
*/
- BUG_ON(!dma_declare_coherent_memory(&dev->dev,
- GAPSPCI_DMA_BASE,
- GAPSPCI_DMA_BASE,
- GAPSPCI_DMA_SIZE,
- DMA_MEMORY_MAP |
- DMA_MEMORY_EXCLUSIVE));
+ res.start = GAPSPCI_DMA_BASE;
+ res.end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1;
+ res.flags = IORESOURCE_MEM;
+ pcibios_resource_to_bus(dev->bus, &region, &res);
+ BUG_ON(dma_declare_coherent_memory(&dev->dev,
+ res.start,
+ region.start,
+ resource_size(&res)));
break;
default:
printk("PCI: Failed resource fixup\n");
@@ -64,7 +71,7 @@ static void gapspci_fixup_resources(struct pci_dev *dev)
}
DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, gapspci_fixup_resources);
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
/*
* The interrupt routing semantics here are quite trivial.
diff --git a/arch/sh/drivers/pci/fixups-landisk.c b/arch/sh/drivers/pci/fixups-landisk.c
index db5b40a98e62..53fa2fc87eec 100644
--- a/arch/sh/drivers/pci/fixups-landisk.c
+++ b/arch/sh/drivers/pci/fixups-landisk.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/pci/fixups-landisk.c
*
@@ -5,9 +6,6 @@
*
* Copyright (C) 2006 kogiidena
* Copyright (C) 2010 Nobuhiro Iwamatsu
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
*/
#include <linux/kernel.h>
#include <linux/types.h>
diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c
index 57ed3f09d0c2..3c9139c5955e 100644
--- a/arch/sh/drivers/pci/fixups-r7780rp.c
+++ b/arch/sh/drivers/pci/fixups-r7780rp.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/pci/fixups-r7780rp.c
*
@@ -5,17 +6,13 @@
*
* Copyright (C) 2003 Lineo uSolutions, Inc.
* Copyright (C) 2004 - 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.
*/
#include <linux/pci.h>
#include <linux/io.h>
#include <linux/sh_intc.h>
#include "pci-sh4.h"
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
return evt2irq(0xa20) + slot;
}
diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c
index eaddb56c45c6..3f0a6fe1610b 100644
--- a/arch/sh/drivers/pci/fixups-rts7751r2d.c
+++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/pci/fixups-rts7751r2d.c
*
@@ -6,10 +7,6 @@
* Copyright (C) 2003 Lineo uSolutions, Inc.
* Copyright (C) 2004 Paul Mundt
* Copyright (C) 2007 Nobuhiro Iwamatsu
- *
- * 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 <linux/pci.h>
#include <mach/lboxre2.h>
@@ -20,18 +17,18 @@
#define PCIMCR_MRSET_OFF 0xBFFFFFFF
#define PCIMCR_RFSH_OFF 0xFFFFFFFB
-static u8 rts7751r2d_irq_tab[] __initdata = {
+static u8 rts7751r2d_irq_tab[] = {
IRQ_PCI_INTA,
IRQ_PCI_INTB,
IRQ_PCI_INTC,
IRQ_PCI_INTD,
};
-static char lboxre2_irq_tab[] __initdata = {
+static char lboxre2_irq_tab[] = {
IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,
};
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
if (mach_is_lboxre2())
return lboxre2_irq_tab[slot];
diff --git a/arch/sh/drivers/pci/fixups-sdk7780.c b/arch/sh/drivers/pci/fixups-sdk7780.c
index c0a015ae6ecf..c306040485bd 100644
--- a/arch/sh/drivers/pci/fixups-sdk7780.c
+++ b/arch/sh/drivers/pci/fixups-sdk7780.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/pci/fixups-sdk7780.c
*
@@ -6,10 +7,6 @@
* Copyright (C) 2003 Lineo uSolutions, Inc.
* Copyright (C) 2004 - 2006 Paul Mundt
* Copyright (C) 2006 Nobuhiro Iwamatsu
- *
- * 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 <linux/pci.h>
#include <linux/io.h>
@@ -22,7 +19,7 @@
#define IRQ_INTD evt2irq(0xa80)
/* IDSEL [16][17][18][19][20][21][22][23][24][25][26][27][28][29][30][31] */
-static char sdk7780_irq_tab[4][16] __initdata = {
+static char sdk7780_irq_tab[4][16] = {
/* INTA */
{ IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1 },
@@ -37,7 +34,7 @@ static char sdk7780_irq_tab[4][16] __initdata = {
-1, -1, -1 },
};
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
return sdk7780_irq_tab[pin-1][slot];
}
diff --git a/arch/sh/drivers/pci/fixups-sdk7786.c b/arch/sh/drivers/pci/fixups-sdk7786.c
index 36eb6fc3c18a..6972af7b4e93 100644
--- a/arch/sh/drivers/pci/fixups-sdk7786.c
+++ b/arch/sh/drivers/pci/fixups-sdk7786.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* SDK7786 FPGA PCIe mux handling
*
* 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) "PCI: " fmt
@@ -56,7 +53,7 @@ static int __init sdk7786_pci_init(void)
/* Warn about forced rerouting if slot#3 is occupied */
if ((data & PCIECR_PRST3) == 0) {
- pr_warning("Unreachable card detected in slot#3\n");
+ pr_warn("Unreachable card detected in slot#3\n");
return -EBUSY;
}
} else
diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c
index 84a88ca92008..608f6521ceff 100644
--- a/arch/sh/drivers/pci/fixups-se7751.c
+++ b/arch/sh/drivers/pci/fixups-se7751.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/types.h>
#include <linux/init.h>
@@ -7,7 +8,7 @@
#include <linux/sh_intc.h>
#include "pci-sh4.h"
-int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)
{
switch (slot) {
case 0: return evt2irq(0x3a0);
diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c
index 16207bef9f52..7ec4a74ab12c 100644
--- a/arch/sh/drivers/pci/fixups-sh03.c
+++ b/arch/sh/drivers/pci/fixups-sh03.c
@@ -1,10 +1,11 @@
+// SPDX-License-Identifier: GPL-2.0
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/pci.h>
#include <linux/sh_intc.h>
-int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
int irq;
diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c
index 6e33ba4cd076..317225c09413 100644
--- a/arch/sh/drivers/pci/fixups-snapgear.c
+++ b/arch/sh/drivers/pci/fixups-snapgear.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/pci/ops-snapgear.c
*
@@ -7,9 +8,6 @@
*
* Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
*
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
* PCI initialization for the SnapGear boards
*/
#include <linux/kernel.h>
@@ -19,7 +17,7 @@
#include <linux/sh_intc.h>
#include "pci-sh4.h"
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
int irq = -1;
diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c
index bd1addb1b8be..b5bb65caa16d 100644
--- a/arch/sh/drivers/pci/fixups-titan.c
+++ b/arch/sh/drivers/pci/fixups-titan.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* arch/sh/drivers/pci/ops-titan.c
*
@@ -6,9 +7,6 @@
* Modified from ops-snapgear.c written by David McCullough
* Highly leveraged from pci-bigsur.c, written by Dustin McIntire.
*
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
* PCI initialization for the Titan boards
*/
#include <linux/kernel.h>
@@ -19,7 +17,7 @@
#include <mach/titan.h>
#include "pci-sh4.h"
-static char titan_irq_tab[] __initdata = {
+static char titan_irq_tab[] = {
TITAN_IRQ_WAN,
TITAN_IRQ_LAN,
TITAN_IRQ_MPCIA,
@@ -27,7 +25,7 @@ static char titan_irq_tab[] __initdata = {
TITAN_IRQ_USB,
};
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
int irq = titan_irq_tab[slot];
diff --git a/arch/sh/drivers/pci/ops-dreamcast.c b/arch/sh/drivers/pci/ops-dreamcast.c
index 16e0a1baad88..517a8a9702f6 100644
--- a/arch/sh/drivers/pci/ops-dreamcast.c
+++ b/arch/sh/drivers/pci/ops-dreamcast.c
@@ -1,12 +1,9 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCI operations for the Sega Dreamcast
*
* Copyright (C) 2001, 2002 M. R. Brown
* Copyright (C) 2002, 2003 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 <linux/sched.h>
diff --git a/arch/sh/drivers/pci/ops-sh4.c b/arch/sh/drivers/pci/ops-sh4.c
index b6234203e0ac..a205be3bfc4a 100644
--- a/arch/sh/drivers/pci/ops-sh4.c
+++ b/arch/sh/drivers/pci/ops-sh4.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Generic SH-4 / SH-4A PCIC operations (SH7751, SH7780).
*
* Copyright (C) 2002 - 2009 Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License v2. See the file "COPYING" in the main directory of this archive
- * for more details.
*/
#include <linux/pci.h>
#include <linux/io.h>
diff --git a/arch/sh/drivers/pci/ops-sh5.c b/arch/sh/drivers/pci/ops-sh5.c
deleted file mode 100644
index 4ce95a001b80..000000000000
--- a/arch/sh/drivers/pci/ops-sh5.c
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Support functions for the SH5 PCI hardware.
- *
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- * Copyright (C) 2003, 2004 Paul Mundt
- * Copyright (C) 2004 Richard Curnow
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- */
-#include <linux/kernel.h>
-#include <linux/rwsem.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/irq.h>
-#include <asm/pci.h>
-#include <asm/io.h>
-#include "pci-sh5.h"
-
-static int sh5pci_read(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 *val)
-{
- SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
-
- switch (size) {
- case 1:
- *val = (u8)SH5PCI_READ_BYTE(PDR + (where & 3));
- break;
- case 2:
- *val = (u16)SH5PCI_READ_SHORT(PDR + (where & 2));
- break;
- case 4:
- *val = SH5PCI_READ(PDR);
- break;
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-static int sh5pci_write(struct pci_bus *bus, unsigned int devfn, int where,
- int size, u32 val)
-{
- SH5PCI_WRITE(PAR, CONFIG_CMD(bus, devfn, where));
-
- switch (size) {
- case 1:
- SH5PCI_WRITE_BYTE(PDR + (where & 3), (u8)val);
- break;
- case 2:
- SH5PCI_WRITE_SHORT(PDR + (where & 2), (u16)val);
- break;
- case 4:
- SH5PCI_WRITE(PDR, val);
- break;
- }
-
- return PCIBIOS_SUCCESSFUL;
-}
-
-struct pci_ops sh5_pci_ops = {
- .read = sh5pci_read,
- .write = sh5pci_write,
-};
diff --git a/arch/sh/drivers/pci/ops-sh7786.c b/arch/sh/drivers/pci/ops-sh7786.c
index 128421009e3f..a10f9f4ebd7f 100644
--- a/arch/sh/drivers/pci/ops-sh7786.c
+++ b/arch/sh/drivers/pci/ops-sh7786.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Generic SH7786 PCI-Express operations.
*
* Copyright (C) 2009 - 2010 Paul Mundt
- *
- * This file is subject to the terms and conditions of the GNU General Public
- * License v2. See the file "COPYING" in the main directory of this archive
- * for more details.
*/
#include <linux/kernel.h>
#include <linux/init.h>
diff --git a/arch/sh/drivers/pci/pci-dreamcast.c b/arch/sh/drivers/pci/pci-dreamcast.c
index 633694193af8..4cff2a8107bf 100644
--- a/arch/sh/drivers/pci/pci-dreamcast.c
+++ b/arch/sh/drivers/pci/pci-dreamcast.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* PCI support for the Sega Dreamcast
*
@@ -7,10 +8,6 @@
* This file originally bore the message (with enclosed-$):
* Id: pci.c,v 1.3 2003/05/04 19:29:46 lethal Exp
* Dreamcast PCI: Supports SEGA Broadband Adaptor only.
- *
- * 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 <linux/sched.h>
diff --git a/arch/sh/drivers/pci/pci-sh4.h b/arch/sh/drivers/pci/pci-sh4.h
index cbf763b3015e..1543c50b6503 100644
--- a/arch/sh/drivers/pci/pci-sh4.h
+++ b/arch/sh/drivers/pci/pci-sh4.h
@@ -1,3 +1,4 @@
+/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __PCI_SH4_H
#define __PCI_SH4_H
@@ -11,14 +12,6 @@
#include <asm/io.h>
-/* startup values */
-#define PCI_PROBE_BIOS 1
-#define PCI_PROBE_CONF1 2
-#define PCI_PROBE_CONF2 4
-#define PCI_NO_CHECKS 0x400
-#define PCI_ASSIGN_ROMS 0x1000
-#define PCI_BIOS_IRQ_SCAN 0x2000
-
#define SH4_PCICR 0x100 /* PCI Control Register */
#define SH4_PCICR_PREFIX 0xA5000000 /* CR prefix for write */
#define SH4_PCICR_FTO 0x00000400 /* TRDY/IRDY Enable */
diff --git a/arch/sh/drivers/pci/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c
deleted file mode 100644
index 16c1e721bf54..000000000000
--- a/arch/sh/drivers/pci/pci-sh5.c
+++ /dev/null
@@ -1,220 +0,0 @@
-/*
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- * Copyright (C) 2003, 2004 Paul Mundt
- * Copyright (C) 2004 Richard Curnow
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Support functions for the SH5 PCI hardware.
- */
-
-#include <linux/kernel.h>
-#include <linux/rwsem.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/init.h>
-#include <linux/errno.h>
-#include <linux/pci.h>
-#include <linux/delay.h>
-#include <linux/types.h>
-#include <linux/irq.h>
-#include <cpu/irq.h>
-#include <asm/pci.h>
-#include <asm/io.h>
-#include "pci-sh5.h"
-
-unsigned long pcicr_virt;
-unsigned long PCI_IO_AREA;
-
-/* Rounds a number UP to the nearest power of two. Used for
- * sizing the PCI window.
- */
-static u32 __init r2p2(u32 num)
-{
- int i = 31;
- u32 tmp = num;
-
- if (num == 0)
- return 0;
-
- do {
- if (tmp & (1 << 31))
- break;
- i--;
- tmp <<= 1;
- } while (i >= 0);
-
- tmp = 1 << i;
- /* If the original number isn't a power of 2, round it up */
- if (tmp != num)
- tmp <<= 1;
-
- return tmp;
-}
-
-static irqreturn_t pcish5_err_irq(int irq, void *dev_id)
-{
- struct pt_regs *regs = get_irq_regs();
- unsigned pci_int, pci_air, pci_cir, pci_aint;
-
- pci_int = SH5PCI_READ(INT);
- pci_cir = SH5PCI_READ(CIR);
- pci_air = SH5PCI_READ(AIR);
-
- if (pci_int) {
- printk("PCI INTERRUPT (at %08llx)!\n", regs->pc);
- printk("PCI INT -> 0x%x\n", pci_int & 0xffff);
- printk("PCI AIR -> 0x%x\n", pci_air);
- printk("PCI CIR -> 0x%x\n", pci_cir);
- SH5PCI_WRITE(INT, ~0);
- }
-
- pci_aint = SH5PCI_READ(AINT);
- if (pci_aint) {
- printk("PCI ARB INTERRUPT!\n");
- printk("PCI AINT -> 0x%x\n", pci_aint);
- printk("PCI AIR -> 0x%x\n", pci_air);
- printk("PCI CIR -> 0x%x\n", pci_cir);
- SH5PCI_WRITE(AINT, ~0);
- }
-
- return IRQ_HANDLED;
-}
-
-static irqreturn_t pcish5_serr_irq(int irq, void *dev_id)
-{
- printk("SERR IRQ\n");
-
- return IRQ_NONE;
-}
-
-static struct resource sh5_pci_resources[2];
-
-static struct pci_channel sh5pci_controller = {
- .pci_ops = &sh5_pci_ops,
- .resources = sh5_pci_resources,
- .nr_resources = ARRAY_SIZE(sh5_pci_resources),
- .mem_offset = 0x00000000,
- .io_offset = 0x00000000,
-};
-
-static int __init sh5pci_init(void)
-{
- unsigned long memStart = __pa(memory_start);
- unsigned long memSize = __pa(memory_end) - memStart;
- u32 lsr0;
- u32 uval;
-
- if (request_irq(IRQ_ERR, pcish5_err_irq,
- 0, "PCI Error",NULL) < 0) {
- printk(KERN_ERR "PCISH5: Cannot hook PCI_PERR interrupt\n");
- return -EINVAL;
- }
-
- if (request_irq(IRQ_SERR, pcish5_serr_irq,
- 0, "PCI SERR interrupt", NULL) < 0) {
- printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");
- return -EINVAL;
- }
-
- pcicr_virt = (unsigned long)ioremap_nocache(SH5PCI_ICR_BASE, 1024);
- if (!pcicr_virt) {
- panic("Unable to remap PCICR\n");
- }
-
- PCI_IO_AREA = (unsigned long)ioremap_nocache(SH5PCI_IO_BASE, 0x10000);
- if (!PCI_IO_AREA) {
- panic("Unable to remap PCIIO\n");
- }
-
- /* Clear snoop registers */
- SH5PCI_WRITE(CSCR0, 0);
- SH5PCI_WRITE(CSCR1, 0);
-
- /* Switch off interrupts */
- SH5PCI_WRITE(INTM, 0);
- SH5PCI_WRITE(AINTM, 0);
- SH5PCI_WRITE(PINTM, 0);
-
- /* Set bus active, take it out of reset */
- uval = SH5PCI_READ(CR);
-
- /* Set command Register */
- SH5PCI_WRITE(CR, uval | CR_LOCK_MASK | CR_CFINT| CR_FTO | CR_PFE |
- CR_PFCS | CR_BMAM);
-
- uval=SH5PCI_READ(CR);
-
- /* Allow it to be a master */
- /* NB - WE DISABLE I/O ACCESS to stop overlap */
- /* set WAIT bit to enable stepping, an attempt to improve stability */
- SH5PCI_WRITE_SHORT(CSR_CMD,
- PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
- PCI_COMMAND_WAIT);
-
- /*
- ** Set translation mapping memory in order to convert the address
- ** used for the main bus, to the PCI internal address.
- */
- SH5PCI_WRITE(MBR,0x40000000);
-
- /* Always set the max size 512M */
- SH5PCI_WRITE(MBMR, PCISH5_MEM_SIZCONV(512*1024*1024));
-
- /*
- ** I/O addresses are mapped at internal PCI specific address
- ** as is described into the configuration bridge table.
- ** These are changed to 0, to allow cards that have legacy
- ** io such as vga to function correctly. We set the SH5 IOBAR to
- ** 256K, which is a bit big as we can only have 64K of address space
- */
-
- SH5PCI_WRITE(IOBR,0x0);
-
- /* Set up a 256K window. Totally pointless waste of address space */
- SH5PCI_WRITE(IOBMR,0);
-
- /* The SH5 has a HUGE 256K I/O region, which breaks the PCI spec.
- * Ideally, we would want to map the I/O region somewhere, but it
- * is so big this is not that easy!
- */
- SH5PCI_WRITE(CSR_IBAR0,~0);
- /* Set memory size value */
- memSize = memory_end - memory_start;
-
- /* Now we set up the mbars so the PCI bus can see the memory of
- * the machine */
- if (memSize < (1024 * 1024)) {
- printk(KERN_ERR "PCISH5: Ridiculous memory size of 0x%lx?\n",
- memSize);
- return -EINVAL;
- }
-
- /* Set LSR 0 */
- lsr0 = (memSize > (512 * 1024 * 1024)) ? 0x1ff00001 :
- ((r2p2(memSize) - 0x100000) | 0x1);
- SH5PCI_WRITE(LSR0, lsr0);
-
- /* Set MBAR 0 */
- SH5PCI_WRITE(CSR_MBAR0, memory_start);
- SH5PCI_WRITE(LAR0, memory_start);
-
- SH5PCI_WRITE(CSR_MBAR1,0);
- SH5PCI_WRITE(LAR1,0);
- SH5PCI_WRITE(LSR1,0);
-
- /* Enable the PCI interrupts on the device */
- SH5PCI_WRITE(INTM, ~0);
- SH5PCI_WRITE(AINTM, ~0);
- SH5PCI_WRITE(PINTM, ~0);
-
- sh5_pci_resources[0].start = PCI_IO_AREA;
- sh5_pci_resources[0].end = PCI_IO_AREA + 0x10000;
-
- sh5_pci_resources[1].start = memStart;
- sh5_pci_resources[1].end = memStart + memSize;
-
- return register_pci_controller(&sh5pci_controller);
-}
-arch_initcall(sh5pci_init);
diff --git a/arch/sh/drivers/pci/pci-sh5.h b/arch/sh/drivers/pci/pci-sh5.h
deleted file mode 100644
index 3f01decb4307..000000000000
--- a/arch/sh/drivers/pci/pci-sh5.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2001 David J. Mckay (david.mckay@st.com)
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
- * Definitions for the SH5 PCI hardware.
- */
-#ifndef __PCI_SH5_H
-#define __PCI_SH5_H
-
-/* Product ID */
-#define PCISH5_PID 0x350d
-
-/* vendor ID */
-#define PCISH5_VID 0x1054
-
-/* Configuration types */
-#define ST_TYPE0 0x00 /* Configuration cycle type 0 */
-#define ST_TYPE1 0x01 /* Configuration cycle type 1 */
-
-/* VCR data */
-#define PCISH5_VCR_STATUS 0x00
-#define PCISH5_VCR_VERSION 0x08
-
-/*
-** ICR register offsets and bits
-*/
-#define PCISH5_ICR_CR 0x100 /* PCI control register values */
-#define CR_PBAM (1<<12)
-#define CR_PFCS (1<<11)
-#define CR_FTO (1<<10)
-#define CR_PFE (1<<9)
-#define CR_TBS (1<<8)
-#define CR_SPUE (1<<7)
-#define CR_BMAM (1<<6)
-#define CR_HOST (1<<5)
-#define CR_CLKEN (1<<4)
-#define CR_SOCS (1<<3)
-#define CR_IOCS (1<<2)
-#define CR_RSTCTL (1<<1)
-#define CR_CFINT (1<<0)
-#define CR_LOCK_MASK 0xa5000000
-
-#define PCISH5_ICR_INT 0x114 /* Interrupt registert values */
-#define INT_MADIM (1<<2)
-
-#define PCISH5_ICR_LSR0 0X104 /* Local space register values */
-#define PCISH5_ICR_LSR1 0X108 /* Local space register values */
-#define PCISH5_ICR_LAR0 0x10c /* Local address register values */
-#define PCISH5_ICR_LAR1 0x110 /* Local address register values */
-#define PCISH5_ICR_INTM 0x118 /* Interrupt mask register values */
-#define PCISH5_ICR_AIR 0x11c /* Interrupt error address information register values */
-#define PCISH5_ICR_CIR 0x120 /* Interrupt error command information register values */
-#define PCISH5_ICR_AINT 0x130 /* Interrupt error arbiter interrupt register values */
-#define PCISH5_ICR_AINTM 0x134 /* Interrupt error arbiter interrupt mask register values */
-#define PCISH5_ICR_BMIR 0x138 /* Interrupt error info register of bus master values */
-#define PCISH5_ICR_PAR 0x1c0 /* Pio address register values */
-#define PCISH5_ICR_MBR 0x1c4 /* Memory space bank register values */
-#define PCISH5_ICR_IOBR 0x1c8 /* I/O space bank register values */
-#define PCISH5_ICR_PINT 0x1cc /* power management interrupt register values */
-#define PCISH5_ICR_PINTM 0x1d0 /* power management interrupt mask register values */
-#define PCISH5_ICR_MBMR 0x1d8 /* memory space bank mask register values */
-#define PCISH5_ICR_IOBMR 0x1dc /* I/O space bank mask register values */
-#define PCISH5_ICR_CSCR0 0x210 /* PCI cache snoop control register 0 */
-#define PCISH5_ICR_CSCR1 0x214 /* PCI cache snoop control register 1 */
-#define PCISH5_ICR_PDR 0x220 /* Pio data register values */
-
-/* These are configs space registers */
-#define PCISH5_ICR_CSR_VID 0x000 /* Vendor id */
-#define PCISH5_ICR_CSR_DID 0x002 /* Device id */
-#define PCISH5_ICR_CSR_CMD 0x004 /* Command register */
-#define PCISH5_ICR_CSR_STATUS 0x006 /* Stautus */
-#define PCISH5_ICR_CSR_IBAR0 0x010 /* I/O base address register */
-#define PCISH5_ICR_CSR_MBAR0 0x014 /* First Memory base address register */
-#define PCISH5_ICR_CSR_MBAR1 0x018 /* Second Memory base address register */
-
-/* Base address of registers */
-#define SH5PCI_ICR_BASE (PHYS_PCI_BLOCK + 0x00040000)
-#define SH5PCI_IO_BASE (PHYS_PCI_BLOCK + 0x00800000)
-/* #define SH5PCI_VCR_BASE (P2SEG_PCICB_BLOCK + P2SEG) */
-
-extern unsigned long pcicr_virt;
-/* Register selection macro */
-#define PCISH5_ICR_REG(x) ( pcicr_virt + (PCISH5_ICR_##x))
-/* #define PCISH5_VCR_REG(x) ( SH5PCI_VCR_BASE (PCISH5_VCR_##x)) */
-
-/* Write I/O functions */
-#define SH5PCI_WRITE(reg,val) __raw_writel((u32)(val),PCISH5_ICR_REG(reg))
-#define SH5PCI_WRITE_SHORT(reg,val) __raw_writew((u16)(val),PCISH5_ICR_REG(reg))
-#define SH5PCI_WRITE_BYTE(reg,val) __raw_writeb((u8)(val),PCISH5_ICR_REG(reg))
-
-/* Read I/O functions */
-#define SH5PCI_READ(reg) __raw_readl(PCISH5_ICR_REG(reg))
-#define SH5PCI_READ_SHORT(reg) __raw_readw(PCISH5_ICR_REG(reg))
-#define SH5PCI_READ_BYTE(reg) __raw_readb(PCISH5_ICR_REG(reg))
-
-/* Set PCI config bits */
-#define SET_CONFIG_BITS(bus,devfn,where) ((((bus) << 16) | ((devfn) << 8) | ((where) & ~3)) | 0x80000000)
-
-/* Set PCI command register */
-#define CONFIG_CMD(bus, devfn, where) SET_CONFIG_BITS(bus->number,devfn,where)
-
-/* Size converters */
-#define PCISH5_MEM_SIZCONV(x) (((x / 0x40000) - 1) << 18)
-#define PCISH5_IO_SIZCONV(x) (((x / 0x40000) - 1) << 18)
-
-extern struct pci_ops sh5_pci_ops;
-
-#endif /* __PCI_SH5_H */
diff --git a/arch/sh/drivers/pci/pci-sh7751.c b/arch/sh/drivers/pci/pci-sh7751.c
index 86adb1e235cd..11ed21c2e9bb 100644
--- a/arch/sh/drivers/pci/pci-sh7751.c
+++ b/arch/sh/drivers/pci/pci-sh7751.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Low-Level PCI Support for the SH7751
*
@@ -5,10 +6,6 @@
* Copyright (C) 2001 Dustin McIntire
*
* With cleanup by Paul van Gool <pvangool@mimotech.com>, 2003.
- *
- * 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 <linux/init.h>
#include <linux/pci.h>
@@ -17,7 +14,7 @@
#include <linux/io.h>
#include "pci-sh4.h"
#include <asm/addrspace.h>
-#include <asm/sizes.h>
+#include <linux/sizes.h>
static int __init __area_sdram_check(struct pci_channel *chan,
unsigned int area)
diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h
index 5ede38c330d3..d1951e50effc 100644
--- a/arch/sh/drivers/pci/pci-sh7751.h
+++ b/arch/sh/drivers/pci/pci-sh7751.h
@@ -1,12 +1,9 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
* Low-Level PCI Support for SH7751 targets
*
* Dustin McIntire (dustin@sensoria.com) (c) 2001
* Paul Mundt (lethal@linux-sh.org) (c) 2003
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
*/
#ifndef _PCI_SH7751_H_
diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c
index 5a6dab6e27d9..9a624a6ee354 100644
--- a/arch/sh/drivers/pci/pci-sh7780.c
+++ b/arch/sh/drivers/pci/pci-sh7780.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Low-Level PCI Support for the SH7780
*
* Copyright (C) 2005 - 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 <linux/types.h>
#include <linux/kernel.h>
@@ -19,7 +16,7 @@
#include <linux/log2.h>
#include "pci-sh4.h"
#include <asm/mmu.h>
-#include <asm/sizes.h>
+#include <linux/sizes.h>
#if defined(CONFIG_CPU_BIG_ENDIAN)
# define PCICR_ENDIANNESS SH4_PCICR_BSWP
@@ -151,7 +148,7 @@ static irqreturn_t sh7780_pci_serr_irq(int irq, void *dev_id)
printk(KERN_DEBUG "PCI: system error received: ");
pcibios_report_status(PCI_STATUS_SIG_SYSTEM_ERROR, 1);
- printk("\n");
+ pr_cont("\n");
/* Deassert SERR */
__raw_writel(SH4_PCIINTM_SDIM, hose->reg_base + SH4_PCIINTM);
@@ -182,7 +179,7 @@ static int __init sh7780_pci_setup_irqs(struct pci_channel *hose)
ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, 0,
"PCI SERR interrupt", hose);
if (unlikely(ret)) {
- printk(KERN_ERR "PCI: Failed hooking SERR IRQ\n");
+ pr_err("PCI: Failed hooking SERR IRQ\n");
return ret;
}
@@ -253,7 +250,7 @@ static int __init sh7780_pci_init(void)
const char *type;
int ret, i;
- printk(KERN_NOTICE "PCI: Starting initialization.\n");
+ pr_notice("PCI: Starting initialization.\n");
chan->reg_base = 0xfe040000;
@@ -273,7 +270,7 @@ static int __init sh7780_pci_init(void)
id = __raw_readw(chan->reg_base + PCI_VENDOR_ID);
if (id != PCI_VENDOR_ID_RENESAS) {
- printk(KERN_ERR "PCI: Unknown vendor ID 0x%04x.\n", id);
+ pr_err("PCI: Unknown vendor ID 0x%04x.\n", id);
return -ENODEV;
}
@@ -284,14 +281,13 @@ static int __init sh7780_pci_init(void)
(id == PCI_DEVICE_ID_RENESAS_SH7785) ? "SH7785" :
NULL;
if (unlikely(!type)) {
- printk(KERN_ERR "PCI: Found an unsupported Renesas host "
- "controller, device id 0x%04x.\n", id);
+ pr_err("PCI: Found an unsupported Renesas host controller, device id 0x%04x.\n",
+ id);
return -EINVAL;
}
- printk(KERN_NOTICE "PCI: Found a Renesas %s host "
- "controller, revision %d.\n", type,
- __raw_readb(chan->reg_base + PCI_REVISION_ID));
+ pr_notice("PCI: Found a Renesas %s host controller, revision %d.\n",
+ type, __raw_readb(chan->reg_base + PCI_REVISION_ID));
/*
* Now throw it in to register initialization mode and
@@ -398,9 +394,9 @@ static int __init sh7780_pci_init(void)
sh7780_pci66_init(chan);
- printk(KERN_NOTICE "PCI: Running at %dMHz.\n",
- (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ) ?
- 66 : 33);
+ pr_notice("PCI: Running at %dMHz.\n",
+ (__raw_readw(chan->reg_base + PCI_STATUS) & PCI_STATUS_66MHZ)
+ ? 66 : 33);
return 0;
diff --git a/arch/sh/drivers/pci/pci-sh7780.h b/arch/sh/drivers/pci/pci-sh7780.h
index 1742e2c9db7a..e2ac770f8e35 100644
--- a/arch/sh/drivers/pci/pci-sh7780.h
+++ b/arch/sh/drivers/pci/pci-sh7780.h
@@ -1,12 +1,9 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
* Low-Level PCI Support for SH7780 targets
*
* Dustin McIntire (dustin@sensoria.com) (c) 2001
* Paul Mundt (lethal@linux-sh.org) (c) 2003
- *
- * May be copied or modified under the terms of the GNU General Public
- * License. See linux/COPYING for more information.
- *
*/
#ifndef _PCI_SH7780_H_
diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c
index 102f5d58b037..a3903304f33f 100644
--- a/arch/sh/drivers/pci/pci.c
+++ b/arch/sh/drivers/pci/pci.c
@@ -1,3 +1,4 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* New-style PCI core.
*
@@ -6,17 +7,12 @@
*
* Modelled after arch/mips/pci/pci.c:
* Copyright (C) 2003, 04 Ralf Baechle (ralf@linux-mips.org)
- *
- * 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 <linux/kernel.h>
#include <linux/mm.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/types.h>
-#include <linux/dma-debug.h>
#include <linux/io.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
@@ -39,12 +35,18 @@ static void pcibios_scanbus(struct pci_channel *hose)
LIST_HEAD(resources);
struct resource *res;
resource_size_t offset;
- int i;
- struct pci_bus *bus;
+ int i, ret;
+ struct pci_host_bridge *bridge;
+
+ bridge = pci_alloc_host_bridge(0);
+ if (!bridge)
+ return;
for (i = 0; i < hose->nr_resources; i++) {
res = hose->resources + i;
offset = 0;
+ if (res->flags & IORESOURCE_DISABLED)
+ continue;
if (res->flags & IORESOURCE_IO)
offset = hose->io_offset;
else if (res->flags & IORESOURCE_MEM)
@@ -52,27 +54,36 @@ static void pcibios_scanbus(struct pci_channel *hose)
pci_add_resource_offset(&resources, res, offset);
}
- bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose,
- &resources);
- hose->bus = bus;
+ list_splice_init(&resources, &bridge->windows);
+ bridge->dev.parent = NULL;
+ bridge->sysdata = hose;
+ bridge->busnr = next_busno;
+ bridge->ops = hose->pci_ops;
+ bridge->swizzle_irq = pci_common_swizzle;
+ bridge->map_irq = pcibios_map_platform_irq;
+
+ ret = pci_scan_root_bus_bridge(bridge);
+ if (ret) {
+ pci_free_host_bridge(bridge);
+ return;
+ }
+
+ hose->bus = bridge->bus;
need_domain_info = need_domain_info || hose->index;
hose->need_domain_info = need_domain_info;
- if (bus) {
- next_busno = bus->busn_res.end + 1;
- /* Don't allow 8-bit bus number overflow inside the hose -
- reserve some space for bridges. */
- if (next_busno > 224) {
- next_busno = 0;
- need_domain_info = 1;
- }
- pci_bus_size_bridges(bus);
- pci_bus_assign_resources(bus);
- pci_enable_bridges(bus);
- } else {
- pci_free_resource_list(&resources);
+ next_busno = hose->bus->busn_res.end + 1;
+ /* Don't allow 8-bit bus number overflow inside the hose -
+ reserve some space for bridges. */
+ if (next_busno > 224) {
+ next_busno = 0;
+ need_domain_info = 1;
}
+
+ pci_bus_size_bridges(hose->bus);
+ pci_bus_assign_resources(hose->bus);
+ pci_bus_add_devices(hose->bus);
}
/*
@@ -89,6 +100,9 @@ int register_pci_controller(struct pci_channel *hose)
for (i = 0; i < hose->nr_resources; i++) {
struct resource *res = hose->resources + i;
+ if (res->flags & IORESOURCE_DISABLED)
+ continue;
+
if (res->flags & IORESOURCE_IO) {
if (request_resource(&ioport_resource, res) < 0)
goto out;
@@ -105,8 +119,7 @@ int register_pci_controller(struct pci_channel *hose)
* Do not panic here but later - this might happen before console init.
*/
if (!hose->io_map_base) {
- printk(KERN_WARNING
- "registering PCI controller with io_map_base unset\n");
+ pr_warn("registering PCI controller with io_map_base unset\n");
}
/*
@@ -130,7 +143,7 @@ out:
for (--i; i >= 0; i--)
release_resource(&hose->resources[i]);
- printk(KERN_WARNING "Skipping PCI bus scan due to resource conflict\n");
+ pr_warn("Skipping PCI bus scan due to resource conflict\n");
return -1;
}
@@ -142,10 +155,6 @@ static int __init pcibios_init(void)
for (hose = hose_head; hose; hose = hose->next)
pcibios_scanbus(hose);
- pci_fixup_irqs(pci_common_swizzle, pcibios_map_platform_irq);
-
- dma_debug_add_bus(&pci_bus_type);
-
pci_initialized = 1;
return 0;
@@ -153,14 +162,6 @@ static int __init pcibios_init(void)
subsys_initcall(pcibios_init);
/*
- * Called after each bus is probed, but before its children
- * are examined.
- */
-void pcibios_fixup_bus(struct pci_bus *bus)
-{
-}
-
-/*
* We need to avoid collisions with `mirrored' VGA ports
* and other strange ISA hardware, so we always want the
* addresses to be allocated in the 0x000-0x0ff region
@@ -187,11 +188,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,
return start;
}
-int pcibios_enable_device(struct pci_dev *dev, int mask)
-{
- return pci_enable_resources(dev, mask);
-}
-
static void __init
pcibios_bus_report_status_early(struct pci_channel *hose,
int top_bus, int current_bus,
@@ -215,8 +211,8 @@ pcibios_bus_report_status_early(struct pci_channel *hose,
pci_devfn, PCI_STATUS,
status & status_mask);
if (warn)
- printk("(%02x:%02x: %04X) ", current_bus,
- pci_devfn, status);
+ pr_cont("(%02x:%02x: %04X) ", current_bus, pci_devfn,
+ status);
}
}
@@ -224,7 +220,7 @@ pcibios_bus_report_status_early(struct pci_channel *hose,
* We can't use pci_find_device() here since we are
* called from interrupt context.
*/
-static void __init_refok
+static void __ref
pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask,
int warn)
{
@@ -251,7 +247,7 @@ pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask,
pci_write_config_word(dev, PCI_STATUS, status & status_mask);
if (warn)
- printk("(%s: %04X) ", pci_name(dev), status);
+ pr_cont("(%s: %04X) ", pci_name(dev), status);
}
list_for_each_entry(dev, &bus->devices, bus_list)
@@ -259,7 +255,7 @@ pcibios_bus_report_status(struct pci_bus *bus, unsigned int status_mask,
pcibios_bus_report_status(dev->subordinate, status_mask, warn);
}
-void __init_refok pcibios_report_status(unsigned int status_mask, int warn)
+void __ref pcibios_report_status(unsigned int status_mask, int warn)
{
struct pci_channel *hose;
@@ -272,27 +268,6 @@ void __init_refok pcibios_report_status(unsigned int status_mask, int warn)
}
}
-int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,
- enum pci_mmap_state mmap_state, int write_combine)
-{
- /*
- * I/O space can be accessed via normal processor loads and stores on
- * this platform but for now we elect not to do this and portable
- * drivers should not do this anyway.
- */
- if (mmap_state == pci_mmap_io)
- return -EINVAL;
-
- /*
- * Ignore write-combine; for now only return uncached mappings.
- */
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
- return remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
- vma->vm_end - vma->vm_start,
- vma->vm_page_prot);
-}
-
#ifndef CONFIG_GENERIC_IOMAP
void __iomem *__pci_ioport_map(struct pci_dev *dev,
diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c
index a162a7f86b2e..a78b9a935585 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.c
+++ b/arch/sh/drivers/pci/pcie-sh7786.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Low-Level PCI Express Support for the SH7786
*
* Copyright (C) 2009 - 2011 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) "PCI: " fmt
@@ -15,12 +12,14 @@
#include <linux/io.h>
#include <linux/async.h>
#include <linux/delay.h>
+#include <linux/dma-map-ops.h>
#include <linux/slab.h>
#include <linux/clk.h>
#include <linux/sh_clk.h>
#include <linux/sh_intc.h>
+#include <cpu/sh7786.h>
#include "pcie-sh7786.h"
-#include <asm/sizes.h>
+#include <linux/sizes.h>
struct sh7786_pcie_port {
struct pci_channel *hose;
@@ -32,6 +31,8 @@ struct sh7786_pcie_port {
static struct sh7786_pcie_port *sh7786_pcie_ports;
static unsigned int nr_ports;
+size_t memsize;
+u64 memstart;
static struct sh7786_pcie_hwops {
int (*core_init)(void);
@@ -40,73 +41,73 @@ static struct sh7786_pcie_hwops {
static struct resource sh7786_pci0_resources[] = {
{
- .name = "PCIe0 IO",
+ .name = "PCIe0 MEM 0",
.start = 0xfd000000,
.end = 0xfd000000 + SZ_8M - 1,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_MEM,
}, {
- .name = "PCIe0 MEM 0",
+ .name = "PCIe0 MEM 1",
.start = 0xc0000000,
.end = 0xc0000000 + SZ_512M - 1,
.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
}, {
- .name = "PCIe0 MEM 1",
+ .name = "PCIe0 MEM 2",
.start = 0x10000000,
.end = 0x10000000 + SZ_64M - 1,
.flags = IORESOURCE_MEM,
}, {
- .name = "PCIe0 MEM 2",
+ .name = "PCIe0 IO",
.start = 0xfe100000,
.end = 0xfe100000 + SZ_1M - 1,
- .flags = IORESOURCE_MEM,
+ .flags = IORESOURCE_IO,
},
};
static struct resource sh7786_pci1_resources[] = {
{
- .name = "PCIe1 IO",
+ .name = "PCIe1 MEM 0",
.start = 0xfd800000,
.end = 0xfd800000 + SZ_8M - 1,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_MEM,
}, {
- .name = "PCIe1 MEM 0",
+ .name = "PCIe1 MEM 1",
.start = 0xa0000000,
.end = 0xa0000000 + SZ_512M - 1,
.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
}, {
- .name = "PCIe1 MEM 1",
+ .name = "PCIe1 MEM 2",
.start = 0x30000000,
.end = 0x30000000 + SZ_256M - 1,
.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
}, {
- .name = "PCIe1 MEM 2",
+ .name = "PCIe1 IO",
.start = 0xfe300000,
.end = 0xfe300000 + SZ_1M - 1,
- .flags = IORESOURCE_MEM,
+ .flags = IORESOURCE_IO,
},
};
static struct resource sh7786_pci2_resources[] = {
{
- .name = "PCIe2 IO",
+ .name = "PCIe2 MEM 0",
.start = 0xfc800000,
.end = 0xfc800000 + SZ_4M - 1,
- .flags = IORESOURCE_IO,
+ .flags = IORESOURCE_MEM,
}, {
- .name = "PCIe2 MEM 0",
+ .name = "PCIe2 MEM 1",
.start = 0x80000000,
.end = 0x80000000 + SZ_512M - 1,
.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
}, {
- .name = "PCIe2 MEM 1",
+ .name = "PCIe2 MEM 2",
.start = 0x20000000,
.end = 0x20000000 + SZ_256M - 1,
.flags = IORESOURCE_MEM | IORESOURCE_MEM_32BIT,
}, {
- .name = "PCIe2 MEM 2",
+ .name = "PCIe2 IO",
.start = 0xfcd00000,
.end = 0xfcd00000 + SZ_1M - 1,
- .flags = IORESOURCE_MEM,
+ .flags = IORESOURCE_IO,
},
};
@@ -138,12 +139,12 @@ static void sh7786_pci_fixup(struct pci_dev *dev)
* Prevent enumeration of root complex resources.
*/
if (pci_is_root_bus(dev->bus) && dev->devfn == 0) {
- int i;
+ struct resource *r;
- for (i = 0; i < DEVICE_COUNT_RESOURCE; i++) {
- dev->resource[i].start = 0;
- dev->resource[i].end = 0;
- dev->resource[i].flags = 0;
+ pci_dev_for_each_resource(dev, r) {
+ r->start = 0;
+ r->end = 0;
+ r->flags = 0;
}
}
}
@@ -301,8 +302,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
{
struct pci_channel *chan = port->hose;
unsigned int data;
- phys_addr_t memphys;
- size_t memsize;
+ phys_addr_t memstart, memend;
int ret, i, win;
/* Begin initialization */
@@ -313,7 +313,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
* class to match. Hardware takes care of propagating the IDSETR
* settings, so there is no need to bother with a quirk.
*/
- pci_write_reg(chan, PCI_CLASS_BRIDGE_PCI << 16, SH4A_PCIEIDSETR1);
+ pci_write_reg(chan, PCI_CLASS_BRIDGE_PCI_NORMAL << 8, SH4A_PCIEIDSETR1);
/* Initialize default capabilities. */
data = pci_read_reg(chan, SH4A_PCIEEXPCAP0);
@@ -357,15 +357,24 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
data |= (0xff << 16);
pci_write_reg(chan, data, SH4A_PCIEMACCTLR);
- memphys = __pa(memory_start);
- memsize = roundup_pow_of_two(memory_end - memory_start);
+ memstart = __pa(memory_start);
+ memend = __pa(memory_end);
+ memsize = roundup_pow_of_two(memend - memstart);
+
+ /*
+ * The start address must be aligned on its size. So we round
+ * it down, and then recalculate the size so that it covers
+ * the entire memory.
+ */
+ memstart = ALIGN_DOWN(memstart, memsize);
+ memsize = roundup_pow_of_two(memend - memstart);
/*
* If there's more than 512MB of memory, we need to roll over to
* LAR1/LAMR1.
*/
if (memsize > SZ_512M) {
- pci_write_reg(chan, memphys + SZ_512M, SH4A_PCIELAR1);
+ pci_write_reg(chan, memstart + SZ_512M, SH4A_PCIELAR1);
pci_write_reg(chan, ((memsize - SZ_512M) - SZ_256) | 1,
SH4A_PCIELAMR1);
memsize = SZ_512M;
@@ -381,7 +390,7 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
* LAR0/LAMR0 covers up to the first 512MB, which is enough to
* cover all of lowmem on most platforms.
*/
- pci_write_reg(chan, memphys, SH4A_PCIELAR0);
+ pci_write_reg(chan, memstart, SH4A_PCIELAR0);
pci_write_reg(chan, (memsize - SZ_256) | 1, SH4A_PCIELAMR0);
/* Finish initialization */
@@ -438,6 +447,9 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
* mode, so just skip them entirely.
*/
if ((res->flags & IORESOURCE_MEM_32BIT) && __in_29bit_mode())
+ res->flags |= IORESOURCE_DISABLED;
+
+ if (res->flags & IORESOURCE_DISABLED)
continue;
pci_write_reg(chan, 0x00000000, SH4A_PCIEPTCTLR(win));
@@ -467,11 +479,17 @@ static int __init pcie_init(struct sh7786_pcie_port *port)
return 0;
}
-int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
+int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
return evt2irq(0xae0);
}
+void pcibios_bus_add_device(struct pci_dev *pdev)
+{
+ dma_direct_set_offset(&pdev->dev, __pa(memory_start),
+ __pa(memory_start) - memstart, memsize);
+}
+
static int __init sh7786_pcie_core_init(void)
{
/* Return the number of ports */
@@ -527,6 +545,7 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {
static int __init sh7786_pcie_init(void)
{
struct clk *platclk;
+ u32 mm_sel;
int i;
printk(KERN_NOTICE "PCI: Starting initialization.\n");
@@ -539,7 +558,7 @@ static int __init sh7786_pcie_init(void)
if (unlikely(nr_ports == 0))
return -ENODEV;
- sh7786_pcie_ports = kzalloc(nr_ports * sizeof(struct sh7786_pcie_port),
+ sh7786_pcie_ports = kcalloc(nr_ports, sizeof(struct sh7786_pcie_port),
GFP_KERNEL);
if (unlikely(!sh7786_pcie_ports))
return -ENOMEM;
@@ -560,6 +579,16 @@ static int __init sh7786_pcie_init(void)
clk_enable(platclk);
+ mm_sel = sh7786_mm_sel();
+
+ /*
+ * Depending on the MMSELR register value, the PCIe0 MEM 1
+ * area may not be available. See Table 13.11 of the SH7786
+ * datasheet.
+ */
+ if (mm_sel != 1 && mm_sel != 2 && mm_sel != 5 && mm_sel != 6)
+ sh7786_pci0_resources[2].flags |= IORESOURCE_DISABLED;
+
printk(KERN_NOTICE "PCI: probing %d ports.\n", nr_ports);
for (i = 0; i < nr_ports; i++) {
diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h
index 1ee054e47eae..ffe383681a0b 100644
--- a/arch/sh/drivers/pci/pcie-sh7786.h
+++ b/arch/sh/drivers/pci/pcie-sh7786.h
@@ -1,12 +1,9 @@
-/*
+/* SPDX-License-Identifier: GPL-2.0
+ *
* SH7786 PCI-Express controller definitions.
*
* Copyright (C) 2008, 2009 Renesas Technology Corp.
* All rights reserved.
- *
- * 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 __PCI_SH7786_H
#define __PCI_SH7786_H
@@ -145,9 +142,6 @@
/* PCIERMSGIER */
#define SH4A_PCIERMSGIER (0x004040) /* R/W - 0x0000 0000 32 */
-/* PCIEPHYCTLR */
-#define SH4A_PCIEPHYCTLR (0x010000) /* R/W - 0x0000 0000 32 */
-
/* PCIEPHYADRR */
#define SH4A_PCIEPHYADRR (0x010004) /* R/W - 0x0000 0000 32 */
#define BITS_ACK (24) // Rev1.171
diff --git a/arch/sh/drivers/platform_early.c b/arch/sh/drivers/platform_early.c
new file mode 100644
index 000000000000..143747c45206
--- /dev/null
+++ b/arch/sh/drivers/platform_early.c
@@ -0,0 +1,340 @@
+// SPDX--License-Identifier: GPL-2.0
+
+#include <asm/platform_early.h>
+#include <linux/mod_devicetable.h>
+#include <linux/pm.h>
+
+static __initdata LIST_HEAD(sh_early_platform_driver_list);
+static __initdata LIST_HEAD(sh_early_platform_device_list);
+
+static const struct platform_device_id *
+platform_match_id(const struct platform_device_id *id,
+ struct platform_device *pdev)
+{
+ while (id->name[0]) {
+ if (strcmp(pdev->name, id->name) == 0) {
+ pdev->id_entry = id;
+ return id;
+ }
+ id++;
+ }
+ return NULL;
+}
+
+static int platform_match(struct device *dev, struct device_driver *drv)
+{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct platform_driver *pdrv = to_platform_driver(drv);
+
+ /* When driver_override is set, only bind to the matching driver */
+ if (pdev->driver_override)
+ return !strcmp(pdev->driver_override, drv->name);
+
+ /* Then try to match against the id table */
+ if (pdrv->id_table)
+ return platform_match_id(pdrv->id_table, pdev) != NULL;
+
+ /* fall-back to driver name match */
+ return (strcmp(pdev->name, drv->name) == 0);
+}
+
+#ifdef CONFIG_PM
+static void device_pm_init_common(struct device *dev)
+{
+ if (!dev->power.early_init) {
+ spin_lock_init(&dev->power.lock);
+ dev->power.qos = NULL;
+ dev->power.early_init = true;
+ }
+}
+
+static void pm_runtime_early_init(struct device *dev)
+{
+ dev->power.disable_depth = 1;
+ device_pm_init_common(dev);
+}
+#else
+static void pm_runtime_early_init(struct device *dev) {}
+#endif
+
+/**
+ * sh_early_platform_driver_register - register early platform driver
+ * @epdrv: sh_early_platform driver structure
+ * @buf: string passed from early_param()
+ *
+ * Helper function for sh_early_platform_init() / sh_early_platform_init_buffer()
+ */
+int __init sh_early_platform_driver_register(struct sh_early_platform_driver *epdrv,
+ char *buf)
+{
+ char *tmp;
+ int n;
+
+ /* Simply add the driver to the end of the global list.
+ * Drivers will by default be put on the list in compiled-in order.
+ */
+ if (!epdrv->list.next) {
+ INIT_LIST_HEAD(&epdrv->list);
+ list_add_tail(&epdrv->list, &sh_early_platform_driver_list);
+ }
+
+ /* If the user has specified device then make sure the driver
+ * gets prioritized. The driver of the last device specified on
+ * command line will be put first on the list.
+ */
+ n = strlen(epdrv->pdrv->driver.name);
+ if (buf && !strncmp(buf, epdrv->pdrv->driver.name, n)) {
+ list_move(&epdrv->list, &sh_early_platform_driver_list);
+
+ /* Allow passing parameters after device name */
+ if (buf[n] == '\0' || buf[n] == ',')
+ epdrv->requested_id = -1;
+ else {
+ epdrv->requested_id = simple_strtoul(&buf[n + 1],
+ &tmp, 10);
+
+ if (buf[n] != '.' || (tmp == &buf[n + 1])) {
+ epdrv->requested_id = EARLY_PLATFORM_ID_ERROR;
+ n = 0;
+ } else
+ n += strcspn(&buf[n + 1], ",") + 1;
+ }
+
+ if (buf[n] == ',')
+ n++;
+
+ if (epdrv->bufsize) {
+ memcpy(epdrv->buffer, &buf[n],
+ min_t(int, epdrv->bufsize, strlen(&buf[n]) + 1));
+ epdrv->buffer[epdrv->bufsize - 1] = '\0';
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * sh_early_platform_add_devices - adds a number of early platform devices
+ * @devs: array of early platform devices to add
+ * @num: number of early platform devices in array
+ *
+ * Used by early architecture code to register early platform devices and
+ * their platform data.
+ */
+void __init sh_early_platform_add_devices(struct platform_device **devs, int num)
+{
+ struct device *dev;
+ int i;
+
+ /* simply add the devices to list */
+ for (i = 0; i < num; i++) {
+ dev = &devs[i]->dev;
+
+ if (!dev->devres_head.next) {
+ pm_runtime_early_init(dev);
+ INIT_LIST_HEAD(&dev->devres_head);
+ list_add_tail(&dev->devres_head,
+ &sh_early_platform_device_list);
+ }
+ }
+}
+
+/**
+ * sh_early_platform_driver_register_all - register early platform drivers
+ * @class_str: string to identify early platform driver class
+ *
+ * Used by architecture code to register all early platform drivers
+ * for a certain class. If omitted then only early platform drivers
+ * with matching kernel command line class parameters will be registered.
+ */
+void __init sh_early_platform_driver_register_all(char *class_str)
+{
+ /* The "class_str" parameter may or may not be present on the kernel
+ * command line. If it is present then there may be more than one
+ * matching parameter.
+ *
+ * Since we register our early platform drivers using early_param()
+ * we need to make sure that they also get registered in the case
+ * when the parameter is missing from the kernel command line.
+ *
+ * We use parse_early_options() to make sure the early_param() gets
+ * called at least once. The early_param() may be called more than
+ * once since the name of the preferred device may be specified on
+ * the kernel command line. sh_early_platform_driver_register() handles
+ * this case for us.
+ */
+ parse_early_options(class_str);
+}
+
+/**
+ * sh_early_platform_match - find early platform device matching driver
+ * @epdrv: early platform driver structure
+ * @id: id to match against
+ */
+static struct platform_device * __init
+sh_early_platform_match(struct sh_early_platform_driver *epdrv, int id)
+{
+ struct platform_device *pd;
+
+ list_for_each_entry(pd, &sh_early_platform_device_list, dev.devres_head)
+ if (platform_match(&pd->dev, &epdrv->pdrv->driver))
+ if (pd->id == id)
+ return pd;
+
+ return NULL;
+}
+
+/**
+ * sh_early_platform_left - check if early platform driver has matching devices
+ * @epdrv: early platform driver structure
+ * @id: return true if id or above exists
+ */
+static int __init sh_early_platform_left(struct sh_early_platform_driver *epdrv,
+ int id)
+{
+ struct platform_device *pd;
+
+ list_for_each_entry(pd, &sh_early_platform_device_list, dev.devres_head)
+ if (platform_match(&pd->dev, &epdrv->pdrv->driver))
+ if (pd->id >= id)
+ return 1;
+
+ return 0;
+}
+
+/**
+ * sh_early_platform_driver_probe_id - probe drivers matching class_str and id
+ * @class_str: string to identify early platform driver class
+ * @id: id to match against
+ * @nr_probe: number of platform devices to successfully probe before exiting
+ */
+static int __init sh_early_platform_driver_probe_id(char *class_str,
+ int id,
+ int nr_probe)
+{
+ struct sh_early_platform_driver *epdrv;
+ struct platform_device *match;
+ int match_id;
+ int n = 0;
+ int left = 0;
+
+ list_for_each_entry(epdrv, &sh_early_platform_driver_list, list) {
+ /* only use drivers matching our class_str */
+ if (strcmp(class_str, epdrv->class_str))
+ continue;
+
+ if (id == -2) {
+ match_id = epdrv->requested_id;
+ left = 1;
+
+ } else {
+ match_id = id;
+ left += sh_early_platform_left(epdrv, id);
+
+ /* skip requested id */
+ switch (epdrv->requested_id) {
+ case EARLY_PLATFORM_ID_ERROR:
+ case EARLY_PLATFORM_ID_UNSET:
+ break;
+ default:
+ if (epdrv->requested_id == id)
+ match_id = EARLY_PLATFORM_ID_UNSET;
+ }
+ }
+
+ switch (match_id) {
+ case EARLY_PLATFORM_ID_ERROR:
+ pr_warn("%s: unable to parse %s parameter\n",
+ class_str, epdrv->pdrv->driver.name);
+ fallthrough;
+ case EARLY_PLATFORM_ID_UNSET:
+ match = NULL;
+ break;
+ default:
+ match = sh_early_platform_match(epdrv, match_id);
+ }
+
+ if (match) {
+ /*
+ * Set up a sensible init_name to enable
+ * dev_name() and others to be used before the
+ * rest of the driver core is initialized.
+ */
+ if (!match->dev.init_name && slab_is_available()) {
+ if (match->id != -1)
+ match->dev.init_name =
+ kasprintf(GFP_KERNEL, "%s.%d",
+ match->name,
+ match->id);
+ else
+ match->dev.init_name =
+ kasprintf(GFP_KERNEL, "%s",
+ match->name);
+
+ if (!match->dev.init_name)
+ return -ENOMEM;
+ }
+
+ if (epdrv->pdrv->probe(match))
+ pr_warn("%s: unable to probe %s early.\n",
+ class_str, match->name);
+ else
+ n++;
+ }
+
+ if (n >= nr_probe)
+ break;
+ }
+
+ if (left)
+ return n;
+ else
+ return -ENODEV;
+}
+
+/**
+ * sh_early_platform_driver_probe - probe a class of registered drivers
+ * @class_str: string to identify early platform driver class
+ * @nr_probe: number of platform devices to successfully probe before exiting
+ * @user_only: only probe user specified early platform devices
+ *
+ * Used by architecture code to probe registered early platform drivers
+ * within a certain class. For probe to happen a registered early platform
+ * device matching a registered early platform driver is needed.
+ */
+int __init sh_early_platform_driver_probe(char *class_str,
+ int nr_probe,
+ int user_only)
+{
+ int k, n, i;
+
+ n = 0;
+ for (i = -2; n < nr_probe; i++) {
+ k = sh_early_platform_driver_probe_id(class_str, i, nr_probe - n);
+
+ if (k < 0)
+ break;
+
+ n += k;
+
+ if (user_only)
+ break;
+ }
+
+ return n;
+}
+
+/**
+ * early_platform_cleanup - clean up early platform code
+ */
+void __init early_platform_cleanup(void)
+{
+ struct platform_device *pd, *pd2;
+
+ /* clean up the devres list used to chain devices */
+ list_for_each_entry_safe(pd, pd2, &sh_early_platform_device_list,
+ dev.devres_head) {
+ list_del(&pd->dev.devres_head);
+ memset(&pd->dev.devres_head, 0, sizeof(pd->dev.devres_head));
+ }
+}
diff --git a/arch/sh/drivers/push-switch.c b/arch/sh/drivers/push-switch.c
index 5bfb341cc5c4..443cc6fd26a8 100644
--- a/arch/sh/drivers/push-switch.c
+++ b/arch/sh/drivers/push-switch.c
@@ -1,11 +1,8 @@
+// SPDX-License-Identifier: GPL-2.0
/*
* Generic push-switch framework
*
* Copyright (C) 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.
*/
#include <linux/init.h>
#include <linux/slab.h>
@@ -24,11 +21,11 @@ static ssize_t switch_show(struct device *dev,
struct push_switch_platform_info *psw_info = dev->platform_data;
return sprintf(buf, "%s\n", psw_info->name);
}
-static DEVICE_ATTR(switch, S_IRUGO, switch_show, NULL);
+static DEVICE_ATTR_RO(switch);
-static void switch_timer(unsigned long data)
+static void switch_timer(struct timer_list *t)
{
- struct push_switch *psw = (struct push_switch *)data;
+ struct push_switch *psw = timer_container_of(psw, t, debounce);
schedule_work(&psw->work);
}
@@ -78,10 +75,7 @@ static int switch_drv_probe(struct platform_device *pdev)
}
INIT_WORK(&psw->work, switch_work_handler);
- init_timer(&psw->debounce);
-
- psw->debounce.function = switch_timer;
- psw->debounce.data = (unsigned long)psw;
+ timer_setup(&psw->debounce, switch_timer, 0);
/* Workqueue API brain-damage */
psw->pdev = pdev;
@@ -97,7 +91,7 @@ err:
return ret;
}
-static int switch_drv_remove(struct platform_device *pdev)
+static void switch_drv_remove(struct platform_device *pdev)
{
struct push_switch *psw = platform_get_drvdata(pdev);
struct push_switch_platform_info *psw_info = pdev->dev.platform_data;
@@ -107,13 +101,11 @@ static int switch_drv_remove(struct platform_device *pdev)
device_remove_file(&pdev->dev, &dev_attr_switch);
platform_set_drvdata(pdev, NULL);
+ timer_shutdown_sync(&psw->debounce);
flush_work(&psw->work);
- del_timer_sync(&psw->debounce);
free_irq(irq, pdev);
kfree(psw);
-
- return 0;
}
static struct platform_driver switch_driver = {
@@ -139,4 +131,5 @@ module_exit(switch_exit);
MODULE_VERSION(DRV_VERSION);
MODULE_AUTHOR("Paul Mundt");
+MODULE_DESCRIPTION("Generic push-switch framework");
MODULE_LICENSE("GPL v2");
diff --git a/arch/sh/drivers/superhyway/Makefile b/arch/sh/drivers/superhyway/Makefile
deleted file mode 100644
index 5b8e0c7ca3a5..000000000000
--- a/arch/sh/drivers/superhyway/Makefile
+++ /dev/null
@@ -1,6 +0,0 @@
-#
-# Makefile for the SuperHyway specific kernel interface routines under Linux.
-#
-
-obj-$(CONFIG_CPU_SUBTYPE_SH4_202) += ops-sh4-202.o
-
diff --git a/arch/sh/drivers/superhyway/ops-sh4-202.c b/arch/sh/drivers/superhyway/ops-sh4-202.c
deleted file mode 100644
index 6da62e9475c4..000000000000
--- a/arch/sh/drivers/superhyway/ops-sh4-202.c
+++ /dev/null
@@ -1,171 +0,0 @@
-/*
- * arch/sh/drivers/superhyway/ops-sh4-202.c
- *
- * SuperHyway bus support for SH4-202
- *
- * Copyright (C) 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 <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/superhyway.h>
-#include <linux/string.h>
-#include <asm/addrspace.h>
-#include <asm/io.h>
-
-#define PHYS_EMI_CBLOCK P4SEGADDR(0x1ec00000)
-#define PHYS_EMI_DBLOCK P4SEGADDR(0x08000000)
-#define PHYS_FEMI_CBLOCK P4SEGADDR(0x1f800000)
-#define PHYS_FEMI_DBLOCK P4SEGADDR(0x00000000)
-
-#define PHYS_EPBR_BLOCK P4SEGADDR(0x1de00000)
-#define PHYS_DMAC_BLOCK P4SEGADDR(0x1fa00000)
-#define PHYS_PBR_BLOCK P4SEGADDR(0x1fc00000)
-
-static struct resource emi_resources[] = {
- [0] = {
- .start = PHYS_EMI_CBLOCK,
- .end = PHYS_EMI_CBLOCK + 0x00300000 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = PHYS_EMI_DBLOCK,
- .end = PHYS_EMI_DBLOCK + 0x08000000 - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct superhyway_device emi_device = {
- .name = "emi",
- .num_resources = ARRAY_SIZE(emi_resources),
- .resource = emi_resources,
-};
-
-static struct resource femi_resources[] = {
- [0] = {
- .start = PHYS_FEMI_CBLOCK,
- .end = PHYS_FEMI_CBLOCK + 0x00100000 - 1,
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = PHYS_FEMI_DBLOCK,
- .end = PHYS_FEMI_DBLOCK + 0x08000000 - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct superhyway_device femi_device = {
- .name = "femi",
- .num_resources = ARRAY_SIZE(femi_resources),
- .resource = femi_resources,
-};
-
-static struct resource epbr_resources[] = {
- [0] = {
- .start = P4SEGADDR(0x1e7ffff8),
- .end = P4SEGADDR(0x1e7ffff8 + (sizeof(u32) * 2) - 1),
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = PHYS_EPBR_BLOCK,
- .end = PHYS_EPBR_BLOCK + 0x00a00000 - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct superhyway_device epbr_device = {
- .name = "epbr",
- .num_resources = ARRAY_SIZE(epbr_resources),
- .resource = epbr_resources,
-};
-
-static struct resource dmac_resource = {
- .start = PHYS_DMAC_BLOCK,
- .end = PHYS_DMAC_BLOCK + 0x00100000 - 1,
- .flags = IORESOURCE_MEM,
-};
-
-static struct superhyway_device dmac_device = {
- .name = "dmac",
- .num_resources = 1,
- .resource = &dmac_resource,
-};
-
-static struct resource pbr_resources[] = {
- [0] = {
- .start = P4SEGADDR(0x1ffffff8),
- .end = P4SEGADDR(0x1ffffff8 + (sizeof(u32) * 2) - 1),
- .flags = IORESOURCE_MEM,
- },
- [1] = {
- .start = PHYS_PBR_BLOCK,
- .end = PHYS_PBR_BLOCK + 0x00400000 - (sizeof(u32) * 2) - 1,
- .flags = IORESOURCE_MEM,
- },
-};
-
-static struct superhyway_device pbr_device = {
- .name = "pbr",
- .num_resources = ARRAY_SIZE(pbr_resources),
- .resource = pbr_resources,
-};
-
-static struct superhyway_device *sh4202_devices[] __initdata = {
- &emi_device, &femi_device, &epbr_device, &dmac_device, &pbr_device,
-};
-
-static int sh4202_read_vcr(unsigned long base, struct superhyway_vcr_info *vcr)
-{
- u32 vcrh, vcrl;
- u64 tmp;
-
- /*
- * XXX: Even though the SH4-202 Evaluation Device documentation
- * indicates that VCRL is mapped first with VCRH at a + 0x04
- * offset, the opposite seems to be true.
- *
- * Some modules (PBR and ePBR for instance) also appear to have
- * VCRL/VCRH flipped in the documentation, but on the SH4-202
- * itself it appears that these are all consistently mapped with
- * VCRH preceding VCRL.
- *
- * Do not trust the documentation, for it is evil.
- */
- vcrh = __raw_readl(base);
- vcrl = __raw_readl(base + sizeof(u32));
-
- tmp = ((u64)vcrh << 32) | vcrl;
- memcpy(vcr, &tmp, sizeof(u64));
-
- return 0;
-}
-
-static int sh4202_write_vcr(unsigned long base, struct superhyway_vcr_info vcr)
-{
- u64 tmp = *(u64 *)&vcr;
-
- __raw_writel((tmp >> 32) & 0xffffffff, base);
- __raw_writel(tmp & 0xffffffff, base + sizeof(u32));
-
- return 0;
-}
-
-static struct superhyway_ops sh4202_superhyway_ops = {
- .read_vcr = sh4202_read_vcr,
- .write_vcr = sh4202_write_vcr,
-};
-
-struct superhyway_bus superhyway_channels[] = {
- { &sh4202_superhyway_ops, },
- { 0, },
-};
-
-int __init superhyway_scan_bus(struct superhyway_bus *bus)
-{
- return superhyway_add_devices(bus, sh4202_devices,
- ARRAY_SIZE(sh4202_devices));
-}
-