diff options
Diffstat (limited to 'arch/sh/drivers')
25 files changed, 418 insertions, 409 deletions
diff --git a/arch/sh/drivers/dma/Kconfig b/arch/sh/drivers/dma/Kconfig index 4d58eb0973d..cfd5b90a862 100644 --- a/arch/sh/drivers/dma/Kconfig +++ b/arch/sh/drivers/dma/Kconfig @@ -40,23 +40,6 @@ config NR_ONCHIP_DMA_CHANNELS  	  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. -config NR_DMA_CHANNELS_BOOL -	depends on SH_DMA -	bool "Override default number of maximum DMA channels" -	help -	  This allows you to forcibly update the maximum number of supported -	  DMA channels for a given board. If this is unset, this will default -	  to the number of channels that the on-chip DMAC has. - -config NR_DMA_CHANNELS -	int "Maximum number of DMA channels" -	depends on SH_DMA && NR_DMA_CHANNELS_BOOL -	default NR_ONCHIP_DMA_CHANNELS -	help -	  This allows you to specify the maximum number of DMA channels to -	  support. Setting this to a higher value allows for cascading DMACs -	  with additional channels. -  config SH_DMABRG  	bool "SH7760 DMABRG support"  	depends on CPU_SUBTYPE_SH7760 diff --git a/arch/sh/drivers/dma/dma-api.c b/arch/sh/drivers/dma/dma-api.c index f46848f088e..c0eec08d8f9 100644 --- a/arch/sh/drivers/dma/dma-api.c +++ b/arch/sh/drivers/dma/dma-api.c @@ -13,6 +13,7 @@  #include <linux/module.h>  #include <linux/spinlock.h>  #include <linux/proc_fs.h> +#include <linux/seq_file.h>  #include <linux/list.h>  #include <linux/platform_device.h>  #include <linux/mm.h> @@ -308,11 +309,9 @@ int dma_extend(unsigned int chan, unsigned long op, void *param)  }  EXPORT_SYMBOL(dma_extend); -static int dma_read_proc(char *buf, char **start, off_t off, -			 int len, int *eof, void *data) +static int dma_proc_show(struct seq_file *m, void *v)  { -	struct dma_info *info; -	char *p = buf; +	struct dma_info *info = v;  	if (list_empty(®istered_dmac_list))  		return 0; @@ -332,14 +331,26 @@ static int dma_read_proc(char *buf, char **start, off_t off,  			if (!(channel->flags & DMA_CONFIGURED))  				continue; -			p += sprintf(p, "%2d: %14s    %s\n", i, -				     info->name, channel->dev_id); +			seq_printf(m, "%2d: %14s    %s\n", i, +				   info->name, channel->dev_id);  		}  	} -	return p - buf; +	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; @@ -412,8 +423,7 @@ EXPORT_SYMBOL(unregister_dmac);  static int __init dma_api_init(void)  {  	printk(KERN_NOTICE "DMA: Registering DMA API.\n"); -	return create_proc_read_entry("dma", 0, 0, dma_read_proc, 0) -		    ? 0 : -ENOMEM; +	return proc_create("dma", 0, NULL, &dma_proc_fops) ? 0 : -ENOMEM;  }  subsys_initcall(dma_api_init); diff --git a/arch/sh/drivers/dma/dma-g2.c b/arch/sh/drivers/dma/dma-g2.c index af7bb589c2c..e1ab6eb3c04 100644 --- a/arch/sh/drivers/dma/dma-g2.c +++ b/arch/sh/drivers/dma/dma-g2.c @@ -170,7 +170,7 @@ static int __init g2_dma_init(void)  {  	int ret; -	ret = request_irq(HW_EVENT_G2_DMA, g2_dma_interrupt, IRQF_DISABLED, +	ret = request_irq(HW_EVENT_G2_DMA, g2_dma_interrupt, 0,  			  "g2 DMA handler", &g2_dma_info);  	if (unlikely(ret))  		return -EINVAL; @@ -181,14 +181,14 @@ static int __init g2_dma_init(void)  	ret = register_dmac(&g2_dma_info);  	if (unlikely(ret != 0)) -		free_irq(HW_EVENT_G2_DMA, 0); +		free_irq(HW_EVENT_G2_DMA, &g2_dma_info);  	return ret;  }  static void __exit g2_dma_exit(void)  { -	free_irq(HW_EVENT_G2_DMA, 0); +	free_irq(HW_EVENT_G2_DMA, &g2_dma_info);  	unregister_dmac(&g2_dma_info);  } diff --git a/arch/sh/drivers/dma/dma-pvr2.c b/arch/sh/drivers/dma/dma-pvr2.c index 3cee58e7f1e..706a3434af7 100644 --- a/arch/sh/drivers/dma/dma-pvr2.c +++ b/arch/sh/drivers/dma/dma-pvr2.c @@ -70,7 +70,6 @@ static int pvr2_xfer_dma(struct dma_channel *chan)  static struct irqaction pvr2_dma_irq = {  	.name		= "pvr2 DMA handler",  	.handler	= pvr2_dma_interrupt, -	.flags		= IRQF_DISABLED,  };  static struct dma_ops pvr2_dma_ops = { diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 827208781ed..b2256562314 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -14,35 +14,72 @@  #include <linux/init.h>  #include <linux/interrupt.h>  #include <linux/module.h> +#include <linux/io.h>  #include <mach-dreamcast/mach/dma.h>  #include <asm/dma.h> -#include <asm/io.h> -#include <asm/dma-sh.h> +#include <asm/dma-register.h> +#include <cpu/dma-register.h> +#include <cpu/dma.h> -#if defined(DMAE1_IRQ) -#define NR_DMAE		2 -#else -#define NR_DMAE		1 +/* + * 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)) + +static unsigned long dma_find_base(unsigned int chan) +{ +	unsigned long base = SH_DMAC_BASE0; + +#ifdef SH_DMAC_BASE1 +	if (chan >= 6) +		base = SH_DMAC_BASE1;  #endif -static const char *dmae_name[] = { -	"DMAC Address Error0", "DMAC Address Error1" -}; +	return base; +} + +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; + +	return base + (chan * 0x10); +} +#ifdef CONFIG_SH_DMA_IRQ_MULTI  static inline unsigned int get_dmte_irq(unsigned int chan)  { -	unsigned int irq = 0; -	if (chan < ARRAY_SIZE(dmte_irq_map)) -		irq = dmte_irq_map[chan]; - -#if defined(CONFIG_SH_DMA_IRQ_MULTI) -	if (irq > DMTE6_IRQ) -		return DMTE6_IRQ; -	return DMTE0_IRQ; +	return chan >= 6 ? DMTE6_IRQ : DMTE0_IRQ; +}  #else -	return irq; + +static unsigned int dmte_irq_map[] = { +	DMTE0_IRQ, DMTE0_IRQ + 1, DMTE0_IRQ + 2, DMTE0_IRQ + 3, + +#ifdef DMTE4_IRQ +	DMTE4_IRQ, DMTE4_IRQ + 1, +#endif + +#ifdef DMTE6_IRQ +	DMTE6_IRQ, DMTE6_IRQ + 1, +#endif + +#ifdef DMTE8_IRQ +	DMTE8_IRQ, DMTE9_IRQ, DMTE10_IRQ, DMTE11_IRQ,  #endif +}; + +static inline unsigned int get_dmte_irq(unsigned int chan) +{ +	return dmte_irq_map[chan];  } +#endif  /*   * We determine the correct shift size based off of the CHCR transmit size @@ -53,9 +90,10 @@ static inline unsigned int get_dmte_irq(unsigned int chan)   * iterations to complete the transfer.   */  static unsigned int ts_shift[] = TS_SHIFT; +  static inline unsigned int calc_xmit_shift(struct dma_channel *chan)  { -	u32 chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR); +	u32 chcr = __raw_readl(dma_base_addr(chan->chan) + CHCR);  	int cnt = ((chcr & CHCR_TS_LOW_MASK) >> CHCR_TS_LOW_SHIFT) |  		((chcr & CHCR_TS_HIGH_MASK) >> CHCR_TS_HIGH_SHIFT); @@ -73,13 +111,13 @@ static irqreturn_t dma_tei(int irq, void *dev_id)  	struct dma_channel *chan = dev_id;  	u32 chcr; -	chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR); +	chcr = __raw_readl(dma_base_addr(chan->chan) + CHCR);  	if (!(chcr & CHCR_TE))  		return IRQ_NONE;  	chcr &= ~(CHCR_IE | CHCR_DE); -	__raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR)); +	__raw_writel(chcr, (dma_base_addr(chan->chan) + CHCR));  	wake_up(&chan->wait_queue); @@ -91,13 +129,8 @@ static int sh_dmac_request_dma(struct dma_channel *chan)  	if (unlikely(!(chan->flags & DMA_TEI_CAPABLE)))  		return 0; -	return request_irq(get_dmte_irq(chan->chan), dma_tei, -#if defined(CONFIG_SH_DMA_IRQ_MULTI) -				IRQF_SHARED, -#else -				IRQF_DISABLED, -#endif -				chan->dev_id, chan); +	return request_irq(get_dmte_irq(chan->chan), dma_tei, IRQF_SHARED, +			   chan->dev_id, chan);  }  static void sh_dmac_free_dma(struct dma_channel *chan) @@ -118,7 +151,7 @@ sh_dmac_configure_channel(struct dma_channel *chan, unsigned long chcr)  		chan->flags &= ~DMA_TEI_CAPABLE;  	} -	__raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR)); +	__raw_writel(chcr, (dma_base_addr(chan->chan) + CHCR));  	chan->flags |= DMA_CONFIGURED;  	return 0; @@ -129,13 +162,13 @@ static void sh_dmac_enable_dma(struct dma_channel *chan)  	int irq;  	u32 chcr; -	chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR); +	chcr = __raw_readl(dma_base_addr(chan->chan) + CHCR);  	chcr |= CHCR_DE;  	if (chan->flags & DMA_TEI_CAPABLE)  		chcr |= CHCR_IE; -	__raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR)); +	__raw_writel(chcr, (dma_base_addr(chan->chan) + CHCR));  	if (chan->flags & DMA_TEI_CAPABLE) {  		irq = get_dmte_irq(chan->chan); @@ -153,9 +186,9 @@ static void sh_dmac_disable_dma(struct dma_channel *chan)  		disable_irq(irq);  	} -	chcr = __raw_readl(dma_base_addr[chan->chan] + CHCR); +	chcr = __raw_readl(dma_base_addr(chan->chan) + CHCR);  	chcr &= ~(CHCR_DE | CHCR_TE | CHCR_IE); -	__raw_writel(chcr, (dma_base_addr[chan->chan] + CHCR)); +	__raw_writel(chcr, (dma_base_addr(chan->chan) + CHCR));  }  static int sh_dmac_xfer_dma(struct dma_channel *chan) @@ -186,13 +219,13 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan)  	 */  	if (chan->sar || (mach_is_dreamcast() &&  			  chan->chan == PVR2_CASCADE_CHAN)) -		__raw_writel(chan->sar, (dma_base_addr[chan->chan]+SAR)); +		__raw_writel(chan->sar, (dma_base_addr(chan->chan) + SAR));  	if (chan->dar || (mach_is_dreamcast() &&  			  chan->chan == PVR2_CASCADE_CHAN)) -		__raw_writel(chan->dar, (dma_base_addr[chan->chan] + DAR)); +		__raw_writel(chan->dar, (dma_base_addr(chan->chan) + DAR));  	__raw_writel(chan->count >> calc_xmit_shift(chan), -		(dma_base_addr[chan->chan] + TCR)); +		(dma_base_addr(chan->chan) + TCR));  	sh_dmac_enable_dma(chan); @@ -201,13 +234,32 @@ static int sh_dmac_xfer_dma(struct dma_channel *chan)  static int sh_dmac_get_dma_residue(struct dma_channel *chan)  { -	if (!(__raw_readl(dma_base_addr[chan->chan] + CHCR) & CHCR_DE)) +	if (!(__raw_readl(dma_base_addr(chan->chan) + CHCR) & CHCR_DE))  		return 0; -	return __raw_readl(dma_base_addr[chan->chan] + TCR) +	return __raw_readl(dma_base_addr(chan->chan) + TCR)  		 << calc_xmit_shift(chan);  } +/* + * DMAOR handling + */ +#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \ +    defined(CONFIG_CPU_SUBTYPE_SH7724)	|| \ +    defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \ +    defined(CONFIG_CPU_SUBTYPE_SH7785) +#define NR_DMAOR	2 +#else +#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) +  static inline int dmaor_reset(int no)  {  	unsigned long dmaor = dmaor_read_reg(no); @@ -228,36 +280,86 @@ static inline int dmaor_reset(int no)  	return 0;  } -#if defined(CONFIG_CPU_SH4) -static irqreturn_t dma_err(int irq, void *dummy) -{ -#if defined(CONFIG_SH_DMA_IRQ_MULTI) -	int cnt = 0; -	switch (irq) { -#if defined(DMTE6_IRQ) && defined(DMAE1_IRQ) -	case DMTE6_IRQ: -		cnt++; +/* + * DMAE handling + */ +#ifdef CONFIG_CPU_SH4 + +#if defined(DMAE1_IRQ) +#define NR_DMAE		2 +#else +#define NR_DMAE		1  #endif -	case DMTE0_IRQ: -		if (dmaor_read_reg(cnt) & (DMAOR_NMIF | DMAOR_AE)) { -			disable_irq(irq); -			/* DMA multi and error IRQ */ -			return IRQ_HANDLED; -		} -	default: -		return IRQ_NONE; -	} + +static const char *dmae_name[] = { +	"DMAC Address Error0", +	"DMAC Address Error1" +}; + +#ifdef CONFIG_SH_DMA_IRQ_MULTI +static inline unsigned int get_dma_error_irq(int n) +{ +	return get_dmte_irq(n * 6); +}  #else -	dmaor_reset(0); -#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \ -		defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \ -		defined(CONFIG_CPU_SUBTYPE_SH7785) -	dmaor_reset(1); + +static unsigned int dmae_irq_map[] = { +	DMAE0_IRQ, + +#ifdef DMAE1_IRQ +	DMAE1_IRQ, +#endif +}; + +static inline unsigned int get_dma_error_irq(int n) +{ +	return dmae_irq_map[n]; +}  #endif + +static irqreturn_t dma_err(int irq, void *dummy) +{ +	int i; + +	for (i = 0; i < NR_DMAOR; i++) +		dmaor_reset(i); +  	disable_irq(irq);  	return IRQ_HANDLED; -#endif +} + +static int dmae_irq_init(void) +{ +	int n; + +	for (n = 0; n < NR_DMAE; n++) { +		int i = request_irq(get_dma_error_irq(n), dma_err, +				    IRQF_SHARED, dmae_name[n], (void *)dmae_name[n]); +		if (unlikely(i < 0)) { +			printk(KERN_ERR "%s request_irq fail\n", dmae_name[n]); +			return i; +		} +	} + +	return 0; +} + +static void dmae_irq_free(void) +{ +	int n; + +	for (n = 0; n < NR_DMAE; n++) +		free_irq(get_dma_error_irq(n), NULL); +} +#else +static inline int dmae_irq_init(void) +{ +	return 0; +} + +static void dmae_irq_free(void) +{  }  #endif @@ -276,72 +378,34 @@ static struct dma_info sh_dmac_info = {  	.flags		= DMAC_CHANNELS_TEI_CAPABLE,  }; -#ifdef CONFIG_CPU_SH4 -static unsigned int get_dma_error_irq(int n) -{ -#if defined(CONFIG_SH_DMA_IRQ_MULTI) -	return (n == 0) ? get_dmte_irq(0) : get_dmte_irq(6); -#else -	return (n == 0) ? DMAE0_IRQ : -#if defined(DMAE1_IRQ) -				DMAE1_IRQ; -#else -				-1; -#endif -#endif -} -#endif -  static int __init sh_dmac_init(void)  {  	struct dma_info *info = &sh_dmac_info; -	int i; - -#ifdef CONFIG_CPU_SH4 -	int n; +	int i, rc; -	for (n = 0; n < NR_DMAE; n++) { -		i = request_irq(get_dma_error_irq(n), dma_err, -#if defined(CONFIG_SH_DMA_IRQ_MULTI) -				IRQF_SHARED, -#else -				IRQF_DISABLED, -#endif -				dmae_name[n], (void *)dmae_name[n]); -		if (unlikely(i < 0)) { -			printk(KERN_ERR "%s request_irq fail\n", dmae_name[n]); -			return i; -		} -	} -#endif /* CONFIG_CPU_SH4 */ +	/* +	 * Initialize DMAE, for parts that support it. +	 */ +	rc = dmae_irq_init(); +	if (unlikely(rc != 0)) +		return rc;  	/*  	 * Initialize DMAOR, and clean up any error flags that may have  	 * been set.  	 */ -	i = dmaor_reset(0); -	if (unlikely(i != 0)) -		return i; -#if defined(CONFIG_CPU_SUBTYPE_SH7723)	|| \ -		defined(CONFIG_CPU_SUBTYPE_SH7780)	|| \ -		defined(CONFIG_CPU_SUBTYPE_SH7785) -	i = dmaor_reset(1); -	if (unlikely(i != 0)) -		return i; -#endif +	for (i = 0; i < NR_DMAOR; i++) { +		rc = dmaor_reset(i); +		if (unlikely(rc != 0)) +			return rc; +	}  	return register_dmac(info);  }  static void __exit sh_dmac_exit(void)  { -#ifdef CONFIG_CPU_SH4 -	int n; - -	for (n = 0; n < NR_DMAE; n++) { -		free_irq(get_dma_error_irq(n), (void *)dmae_name[n]); -	} -#endif /* CONFIG_CPU_SH4 */ +	dmae_irq_free();  	unregister_dmac(&sh_dmac_info);  } diff --git a/arch/sh/drivers/dma/dma-sysfs.c b/arch/sh/drivers/dma/dma-sysfs.c index 1ee631d3725..4b15feda54b 100644 --- a/arch/sh/drivers/dma/dma-sysfs.c +++ b/arch/sh/drivers/dma/dma-sysfs.c @@ -11,23 +11,25 @@   */  #include <linux/kernel.h>  #include <linux/init.h> -#include <linux/sysdev.h> +#include <linux/stat.h> +#include <linux/device.h>  #include <linux/platform_device.h>  #include <linux/err.h>  #include <linux/string.h>  #include <asm/dma.h> -static struct sysdev_class dma_sysclass = { +static struct bus_type dma_subsys = {  	.name = "dma", +	.dev_name = "dma",  }; -static ssize_t dma_show_devices(struct sys_device *dev, -				struct sysdev_attribute *attr, char *buf) +static ssize_t dma_show_devices(struct device *dev, +				struct device_attribute *attr, char *buf)  {  	ssize_t len = 0;  	int i; -	for (i = 0; i < MAX_DMA_CHANNELS; i++) { +	for (i = 0; i < 16; i++) {  		struct dma_info *info = get_dma_info(i);  		struct dma_channel *channel = get_dma_channel(i); @@ -42,29 +44,29 @@ static ssize_t dma_show_devices(struct sys_device *dev,  	return len;  } -static SYSDEV_ATTR(devices, S_IRUGO, dma_show_devices, NULL); +static DEVICE_ATTR(devices, S_IRUGO, dma_show_devices, NULL); -static int __init dma_sysclass_init(void) +static int __init dma_subsys_init(void)  {  	int ret; -	ret = sysdev_class_register(&dma_sysclass); +	ret = subsys_system_register(&dma_subsys, NULL);  	if (unlikely(ret))  		return ret; -	return sysfs_create_file(&dma_sysclass.kset.kobj, &attr_devices.attr); +	return device_create_file(dma_subsys.dev_root, &dev_attr_devices);  } -postcore_initcall(dma_sysclass_init); +postcore_initcall(dma_subsys_init); -static ssize_t dma_show_dev_id(struct sys_device *dev, -				struct sysdev_attribute *attr, char *buf) +static ssize_t dma_show_dev_id(struct device *dev, +				struct device_attribute *attr, char *buf)  {  	struct dma_channel *channel = to_dma_channel(dev);  	return sprintf(buf, "%s\n", channel->dev_id);  } -static ssize_t dma_store_dev_id(struct sys_device *dev, -				struct sysdev_attribute *attr, +static ssize_t dma_store_dev_id(struct device *dev, +				struct device_attribute *attr,  				const char *buf, size_t count)  {  	struct dma_channel *channel = to_dma_channel(dev); @@ -72,10 +74,10 @@ static ssize_t dma_store_dev_id(struct sys_device *dev,  	return count;  } -static SYSDEV_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id); +static DEVICE_ATTR(dev_id, S_IRUGO | S_IWUSR, dma_show_dev_id, dma_store_dev_id); -static ssize_t dma_store_config(struct sys_device *dev, -				struct sysdev_attribute *attr, +static ssize_t dma_store_config(struct device *dev, +				struct device_attribute *attr,  				const char *buf, size_t count)  {  	struct dma_channel *channel = to_dma_channel(dev); @@ -87,17 +89,17 @@ static ssize_t dma_store_config(struct sys_device *dev,  	return count;  } -static SYSDEV_ATTR(config, S_IWUSR, NULL, dma_store_config); +static DEVICE_ATTR(config, S_IWUSR, NULL, dma_store_config); -static ssize_t dma_show_mode(struct sys_device *dev, -				struct sysdev_attribute *attr, char *buf) +static ssize_t dma_show_mode(struct device *dev, +				struct device_attribute *attr, char *buf)  {  	struct dma_channel *channel = to_dma_channel(dev);  	return sprintf(buf, "0x%08x\n", channel->mode);  } -static ssize_t dma_store_mode(struct sys_device *dev, -			      struct sysdev_attribute *attr, +static ssize_t dma_store_mode(struct device *dev, +			      struct device_attribute *attr,  			      const char *buf, size_t count)  {  	struct dma_channel *channel = to_dma_channel(dev); @@ -105,38 +107,38 @@ static ssize_t dma_store_mode(struct sys_device *dev,  	return count;  } -static SYSDEV_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode); +static DEVICE_ATTR(mode, S_IRUGO | S_IWUSR, dma_show_mode, dma_store_mode);  #define dma_ro_attr(field, fmt)						\ -static ssize_t dma_show_##field(struct sys_device *dev, 		\ -				struct sysdev_attribute *attr, char *buf)\ +static ssize_t dma_show_##field(struct device *dev,		\ +				struct device_attribute *attr, char *buf)\  {									\  	struct dma_channel *channel = to_dma_channel(dev);		\  	return sprintf(buf, fmt, channel->field);			\  }									\ -static SYSDEV_ATTR(field, S_IRUGO, dma_show_##field, NULL); +static DEVICE_ATTR(field, S_IRUGO, dma_show_##field, NULL);  dma_ro_attr(count, "0x%08x\n");  dma_ro_attr(flags, "0x%08lx\n");  int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info)  { -	struct sys_device *dev = &chan->dev; +	struct device *dev = &chan->dev;  	char name[16];  	int ret;  	dev->id  = chan->vchan; -	dev->cls = &dma_sysclass; +	dev->bus = &dma_subsys; -	ret = sysdev_register(dev); +	ret = device_register(dev);  	if (ret)  		return ret; -	ret |= sysdev_create_file(dev, &attr_dev_id); -	ret |= sysdev_create_file(dev, &attr_count); -	ret |= sysdev_create_file(dev, &attr_mode); -	ret |= sysdev_create_file(dev, &attr_flags); -	ret |= sysdev_create_file(dev, &attr_config); +	ret |= device_create_file(dev, &dev_attr_dev_id); +	ret |= device_create_file(dev, &dev_attr_count); +	ret |= device_create_file(dev, &dev_attr_mode); +	ret |= device_create_file(dev, &dev_attr_flags); +	ret |= device_create_file(dev, &dev_attr_config);  	if (unlikely(ret)) {  		dev_err(&info->pdev->dev, "Failed creating attrs\n"); @@ -149,17 +151,17 @@ int dma_create_sysfs_files(struct dma_channel *chan, struct dma_info *info)  void dma_remove_sysfs_files(struct dma_channel *chan, struct dma_info *info)  { -	struct sys_device *dev = &chan->dev; +	struct device *dev = &chan->dev;  	char name[16]; -	sysdev_remove_file(dev, &attr_dev_id); -	sysdev_remove_file(dev, &attr_count); -	sysdev_remove_file(dev, &attr_mode); -	sysdev_remove_file(dev, &attr_flags); -	sysdev_remove_file(dev, &attr_config); +	device_remove_file(dev, &dev_attr_dev_id); +	device_remove_file(dev, &dev_attr_count); +	device_remove_file(dev, &dev_attr_mode); +	device_remove_file(dev, &dev_attr_flags); +	device_remove_file(dev, &dev_attr_config);  	snprintf(name, sizeof(name), "dma%d", chan->chan);  	sysfs_remove_link(&info->pdev->dev.kobj, name); -	sysdev_unregister(dev); +	device_unregister(dev);  } diff --git a/arch/sh/drivers/dma/dmabrg.c b/arch/sh/drivers/dma/dmabrg.c index 6ab9c4a1543..c0dd904483c 100644 --- a/arch/sh/drivers/dma/dmabrg.c +++ b/arch/sh/drivers/dma/dmabrg.c @@ -174,23 +174,23 @@ static int __init dmabrg_init(void)  	or = __raw_readl(DMAOR);  	__raw_writel(or | DMAOR_BRG | DMAOR_DMEN, DMAOR); -	ret = request_irq(DMABRGI0, dmabrg_irq, IRQF_DISABLED, +	ret = request_irq(DMABRGI0, dmabrg_irq, 0,  			"DMABRG USB address error", NULL);  	if (ret)  		goto out0; -	ret = request_irq(DMABRGI1, dmabrg_irq, IRQF_DISABLED, +	ret = request_irq(DMABRGI1, dmabrg_irq, 0,  			"DMABRG Transfer End", NULL);  	if (ret)  		goto out1; -	ret = request_irq(DMABRGI2, dmabrg_irq, IRQF_DISABLED, +	ret = request_irq(DMABRGI2, dmabrg_irq, 0,  			"DMABRG Transfer Half", NULL);  	if (ret == 0)  		return ret; -	free_irq(DMABRGI1, 0); -out1:	free_irq(DMABRGI0, 0); +	free_irq(DMABRGI1, NULL); +out1:	free_irq(DMABRGI0, NULL);  out0:	kfree(dmabrg_handlers);  	return ret;  } diff --git a/arch/sh/drivers/pci/fixups-cayman.c b/arch/sh/drivers/pci/fixups-cayman.c index b68b61d22c6..edc2fb7a5bb 100644 --- a/arch/sh/drivers/pci/fixups-cayman.c +++ b/arch/sh/drivers/pci/fixups-cayman.c @@ -5,7 +5,7 @@  #include <cpu/irq.h>  #include "pci-sh5.h" -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	int result = -1; diff --git a/arch/sh/drivers/pci/fixups-dreamcast.c b/arch/sh/drivers/pci/fixups-dreamcast.c index 942ef4f155f..1d1c5a227e5 100644 --- a/arch/sh/drivers/pci/fixups-dreamcast.c +++ b/arch/sh/drivers/pci/fixups-dreamcast.c @@ -28,9 +28,11 @@  #include <asm/irq.h>  #include <mach/pci.h> -static void __init gapspci_fixup_resources(struct pci_dev *dev) +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,11 +52,21 @@ static void __init 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.  		 */ +		res.start = GAPSPCI_DMA_BASE; +		res.end = GAPSPCI_DMA_BASE + GAPSPCI_DMA_SIZE - 1; +		res.flags = IORESOURCE_MEM; +		pcibios_resource_to_bus(dev->bus, ®ion, &res);  		BUG_ON(!dma_declare_coherent_memory(&dev->dev, -						GAPSPCI_DMA_BASE, -						GAPSPCI_DMA_BASE, -						GAPSPCI_DMA_SIZE, +						res.start, +						region.start, +						resource_size(&res),  						DMA_MEMORY_MAP |  						DMA_MEMORY_EXCLUSIVE));  		break; @@ -64,7 +76,7 @@ static void __init 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(struct pci_dev *dev, u8 slot, u8 pin) +int __init 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 bb1a6bb5149..db5b40a98e6 100644 --- a/arch/sh/drivers/pci/fixups-landisk.c +++ b/arch/sh/drivers/pci/fixups-landisk.c @@ -1,9 +1,10 @@  /* - * arch/sh/drivers/pci/ops-landisk.c + * arch/sh/drivers/pci/fixups-landisk.c   *   * PCI initialization for the I-O DATA Device, Inc. LANDISK board   *   * 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. @@ -13,9 +14,13 @@  #include <linux/init.h>  #include <linux/delay.h>  #include <linux/pci.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" -int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +#define PCIMCR_MRSET_OFF	0xBFFFFFFF +#define PCIMCR_RFSH_OFF		0xFFFFFFFB + +int pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)  {  	/*  	 * slot0: pin1-4 = irq5,6,7,8 @@ -23,12 +28,32 @@ int pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin)  	 * slot2: pin1-4 = irq7,8,5,6  	 * slot3: pin1-4 = irq8,5,6,7  	 */ -	int irq = ((slot + pin - 1) & 0x3) + 5; +	int irq = ((slot + pin - 1) & 0x3) + evt2irq(0x2a0);  	if ((slot | (pin - 1)) > 0x3) { -		printk("PCI: Bad IRQ mapping request for slot %d pin %c\n", +		printk(KERN_WARNING "PCI: Bad IRQ mapping request for slot %d pin %c\n",  		       slot, pin - 1 + 'A');  		return -1;  	}  	return irq;  } + +int pci_fixup_pcic(struct pci_channel *chan) +{ +	unsigned long bcr1, mcr; + +	bcr1 = __raw_readl(SH7751_BCR1); +	bcr1 |= 0x40080000;	/* Enable Bit 19 BREQEN, set PCIC to slave */ +	pci_write_reg(chan, bcr1, SH4_PCIBCR1); + +	mcr = __raw_readl(SH7751_MCR); +	mcr = (mcr & PCIMCR_MRSET_OFF) & PCIMCR_RFSH_OFF; +	pci_write_reg(chan, mcr, SH4_PCIMCR); + +	pci_write_reg(chan, 0x0c000000, SH7751_PCICONF5); +	pci_write_reg(chan, 0xd0000000, SH7751_PCICONF6); +	pci_write_reg(chan, 0x0c000000, SH4_PCILAR0); +	pci_write_reg(chan, 0x00000000, SH4_PCILAR1); + +	return 0; +} diff --git a/arch/sh/drivers/pci/fixups-r7780rp.c b/arch/sh/drivers/pci/fixups-r7780rp.c index 08b2d8658a0..57ed3f09d0c 100644 --- a/arch/sh/drivers/pci/fixups-r7780rp.c +++ b/arch/sh/drivers/pci/fixups-r7780rp.c @@ -12,13 +12,10 @@   */  #include <linux/pci.h>  #include <linux/io.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" -static char irq_tab[] __initdata = { -	65, 66, 67, 68, -}; - -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)  { -	return irq_tab[slot]; +	return evt2irq(0xa20) + slot;  } diff --git a/arch/sh/drivers/pci/fixups-rts7751r2d.c b/arch/sh/drivers/pci/fixups-rts7751r2d.c index e248516118a..eaddb56c45c 100644 --- a/arch/sh/drivers/pci/fixups-rts7751r2d.c +++ b/arch/sh/drivers/pci/fixups-rts7751r2d.c @@ -31,7 +31,7 @@ static char lboxre2_irq_tab[] __initdata = {  	IRQ_ETH0, IRQ_ETH1, IRQ_INTA, IRQ_INTD,  }; -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init 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 0930f988ac2..c0a015ae6ec 100644 --- a/arch/sh/drivers/pci/fixups-sdk7780.c +++ b/arch/sh/drivers/pci/fixups-sdk7780.c @@ -13,21 +13,31 @@   */  #include <linux/pci.h>  #include <linux/io.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" +#define IRQ_INTA	evt2irq(0xa20) +#define IRQ_INTB	evt2irq(0xa40) +#define IRQ_INTC	evt2irq(0xa60) +#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 = {  	/* INTA */ -	{ 65, 68, 67, 68, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +	{ IRQ_INTA, IRQ_INTD, IRQ_INTC, IRQ_INTD, -1, -1, -1, -1, -1, -1, +	  -1, -1, -1, -1, -1, -1 },  	/* INTB */ -	{ 66, 65, -1, 65, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +	{ IRQ_INTB, IRQ_INTA, -1, IRQ_INTA, -1, -1, -1, -1, -1, -1, -1, -1, +	  -1, -1, -1, -1 },  	/* INTC */ -	{ 67, 66, -1, 66, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +	{ IRQ_INTC, IRQ_INTB, -1, IRQ_INTB, -1, -1, -1, -1, -1, -1, -1, -1, +	  -1, -1, -1, -1 },  	/* INTD */ -	{ 68, 67, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }, +	{ IRQ_INTD, IRQ_INTC, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, +	  -1, -1, -1 },  }; -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init 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 0e18ee33255..36eb6fc3c18 100644 --- a/arch/sh/drivers/pci/fixups-sdk7786.c +++ b/arch/sh/drivers/pci/fixups-sdk7786.c @@ -23,9 +23,9 @@   * Misconfigurations can be detected through the FPGA via the slot   * resistors to determine card presence. Hotplug remains unsupported.   */ -static unsigned int slot4en __devinitdata; +static unsigned int slot4en __initdata; -char *__devinit pcibios_setup(char *str) +char *__init pcibios_setup(char *str)  {  	if (strcmp(str, "slot4en") == 0) {  		slot4en = 1; diff --git a/arch/sh/drivers/pci/fixups-se7751.c b/arch/sh/drivers/pci/fixups-se7751.c index a4c7d3a4efc..84a88ca9200 100644 --- a/arch/sh/drivers/pci/fixups-se7751.c +++ b/arch/sh/drivers/pci/fixups-se7751.c @@ -4,13 +4,14 @@  #include <linux/delay.h>  #include <linux/pci.h>  #include <linux/io.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" -int __init pcibios_map_platform_irq(u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *, u8 slot, u8 pin)  {          switch (slot) { -        case 0: return 13; -        case 1: return 13;	/* AMD Ethernet controller */ +        case 0: return evt2irq(0x3a0); +        case 1: return evt2irq(0x3a0);	/* AMD Ethernet controller */          case 2: return -1;          case 3: return -1;          case 4: return -1; diff --git a/arch/sh/drivers/pci/fixups-sh03.c b/arch/sh/drivers/pci/fixups-sh03.c index 2e8a18b7ee5..16207bef9f5 100644 --- a/arch/sh/drivers/pci/fixups-sh03.c +++ b/arch/sh/drivers/pci/fixups-sh03.c @@ -2,28 +2,29 @@  #include <linux/init.h>  #include <linux/types.h>  #include <linux/pci.h> +#include <linux/sh_intc.h> -int __init pcibios_map_platform_irq(struct pci_dev *dev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *dev, u8 slot, u8 pin)  {  	int irq;  	if (dev->bus->number == 0) {  		switch (slot) { -		case 4: return 5;	/* eth0       */ -		case 8: return 5;	/* eth1       */ -		case 6: return 2;	/* PCI bridge */ +		case 4: return evt2irq(0x2a0);	/* eth0       */ +		case 8: return evt2irq(0x2a0);	/* eth1       */ +		case 6: return evt2irq(0x240);	/* PCI bridge */  		default:  			printk(KERN_ERR "PCI: Bad IRQ mapping request "  					"for slot %d\n", slot); -			return 2; +			return evt2irq(0x240);  		}  	} else {  		switch (pin) { -		case 0:   irq =  2; break; -		case 1:   irq =  2; break; -		case 2:   irq =  2; break; -		case 3:   irq =  2; break; -		case 4:   irq =  2; break; +		case 0:   irq =  evt2irq(0x240); break; +		case 1:   irq =  evt2irq(0x240); break; +		case 2:   irq =  evt2irq(0x240); break; +		case 3:   irq =  evt2irq(0x240); break; +		case 4:   irq =  evt2irq(0x240); break;  		default:  irq = -1; break;  		}  	} diff --git a/arch/sh/drivers/pci/fixups-snapgear.c b/arch/sh/drivers/pci/fixups-snapgear.c index 5a39ecc1adb..6e33ba4cd07 100644 --- a/arch/sh/drivers/pci/fixups-snapgear.c +++ b/arch/sh/drivers/pci/fixups-snapgear.c @@ -16,19 +16,20 @@  #include <linux/types.h>  #include <linux/init.h>  #include <linux/pci.h> +#include <linux/sh_intc.h>  #include "pci-sh4.h" -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)  {  	int irq = -1;  	switch (slot) {  	case 8:  /* the PCI bridge */ break; -	case 11: irq = 8;  break; /* USB    */ -	case 12: irq = 11; break; /* PCMCIA */ -	case 13: irq = 5;  break; /* eth0   */ -	case 14: irq = 8;  break; /* eth1   */ -	case 15: irq = 11; break; /* safenet (unused) */ +	case 11: irq = evt2irq(0x300); break; /* USB    */ +	case 12: irq = evt2irq(0x360); break; /* PCMCIA */ +	case 13: irq = evt2irq(0x2a0); break; /* eth0   */ +	case 14: irq = evt2irq(0x300); break; /* eth1   */ +	case 15: irq = evt2irq(0x360); break; /* safenet (unused) */  	}  	printk("PCI: Mapping SnapGear IRQ for slot %d, pin %c to irq %d\n", diff --git a/arch/sh/drivers/pci/fixups-titan.c b/arch/sh/drivers/pci/fixups-titan.c index 3a79fa8254a..bd1addb1b8b 100644 --- a/arch/sh/drivers/pci/fixups-titan.c +++ b/arch/sh/drivers/pci/fixups-titan.c @@ -27,7 +27,7 @@ static char titan_irq_tab[] __initdata = {  	TITAN_IRQ_USB,  }; -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init 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/pci-sh5.c b/arch/sh/drivers/pci/pci-sh5.c index 0bf296c7879..16c1e721bf5 100644 --- a/arch/sh/drivers/pci/pci-sh5.c +++ b/arch/sh/drivers/pci/pci-sh5.c @@ -107,13 +107,13 @@ static int __init sh5pci_init(void)  	u32 uval;          if (request_irq(IRQ_ERR, pcish5_err_irq, -                        IRQF_DISABLED, "PCI Error",NULL) < 0) { +                        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, -                        IRQF_DISABLED, "PCI SERR interrupt", NULL) < 0) { +                        0, "PCI SERR interrupt", NULL) < 0) {                  printk(KERN_ERR "PCISH5: Cannot hook PCI_SERR interrupt\n");                  return -EINVAL;          } diff --git a/arch/sh/drivers/pci/pci-sh7751.h b/arch/sh/drivers/pci/pci-sh7751.h index 4983a4d2035..5ede38c330d 100644 --- a/arch/sh/drivers/pci/pci-sh7751.h +++ b/arch/sh/drivers/pci/pci-sh7751.h @@ -61,7 +61,7 @@    #define SH7751_PCICONF3_BIST7      0x80000000  /* Bist Supported */    #define SH7751_PCICONF3_BIST6      0x40000000  /* Bist Executing */    #define SH7751_PCICONF3_BIST3_0    0x0F000000  /* Bist Passed */ -  #define SH7751_PCICONF3_HD7        0x00800000  /* Single Funtion device */ +  #define SH7751_PCICONF3_HD7        0x00800000  /* Single Function device */    #define SH7751_PCICONF3_HD6_0      0x007F0000  /* Configuration Layout */    #define SH7751_PCICONF3_LAT        0x0000FF00  /* Latency Timer */    #define SH7751_PCICONF3_CLS        0x000000FF  /* Cache Line Size */ diff --git a/arch/sh/drivers/pci/pci-sh7780.c b/arch/sh/drivers/pci/pci-sh7780.c index edb7cca1488..5a6dab6e27d 100644 --- a/arch/sh/drivers/pci/pci-sh7780.c +++ b/arch/sh/drivers/pci/pci-sh7780.c @@ -21,6 +21,13 @@  #include <asm/mmu.h>  #include <asm/sizes.h> +#if defined(CONFIG_CPU_BIG_ENDIAN) +# define PCICR_ENDIANNESS SH4_PCICR_BSWP +#else +# define PCICR_ENDIANNESS 0 +#endif + +  static struct resource sh7785_pci_resources[] = {  	{  		.name	= "PCI IO", @@ -74,7 +81,7 @@ struct pci_errors {  	{ SH4_PCIINT_MLCK,	"master lock error" },  	{ SH4_PCIINT_TABT,	"target-target abort" },  	{ SH4_PCIINT_TRET,	"target retry time out" }, -	{ SH4_PCIINT_MFDE,	"master function disable erorr" }, +	{ SH4_PCIINT_MFDE,	"master function disable error" },  	{ SH4_PCIINT_PRTY,	"address parity error" },  	{ SH4_PCIINT_SERR,	"SERR" },  	{ SH4_PCIINT_TWDP,	"data parity error for target write" }, @@ -172,7 +179,7 @@ static int __init sh7780_pci_setup_irqs(struct pci_channel *hose)  		     PCI_STATUS_SIG_TARGET_ABORT | \  		     PCI_STATUS_PARITY, hose->reg_base + PCI_STATUS); -	ret = request_irq(hose->serr_irq, sh7780_pci_serr_irq, IRQF_DISABLED, +	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"); @@ -254,7 +261,7 @@ static int __init sh7780_pci_init(void)  	__raw_writel(PCIECR_ENBL, PCIECR);  	/* Reset */ -	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST, +	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_PRST | PCICR_ENDIANNESS,  		     chan->reg_base + SH4_PCICR);  	/* @@ -290,7 +297,8 @@ static int __init sh7780_pci_init(void)  	 * Now throw it in to register initialization mode and  	 * start the real work.  	 */ -	__raw_writel(SH4_PCICR_PREFIX, chan->reg_base + SH4_PCICR); +	__raw_writel(SH4_PCICR_PREFIX | PCICR_ENDIANNESS, +		     chan->reg_base + SH4_PCICR);  	memphys = __pa(memory_start);  	memsize = roundup_pow_of_two(memory_end - memory_start); @@ -380,7 +388,8 @@ static int __init sh7780_pci_init(void)  	 * Initialization mode complete, release the control register and  	 * enable round robin mode to stop device overruns/starvation.  	 */ -	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO, +	__raw_writel(SH4_PCICR_PREFIX | SH4_PCICR_CFIN | SH4_PCICR_FTO | +		     PCICR_ENDIANNESS,  		     chan->reg_base + SH4_PCICR);  	ret = register_pci_controller(chan); diff --git a/arch/sh/drivers/pci/pci.c b/arch/sh/drivers/pci/pci.c index 60ee09a4e12..1bc09ee7948 100644 --- a/arch/sh/drivers/pci/pci.c +++ b/arch/sh/drivers/pci/pci.c @@ -20,6 +20,7 @@  #include <linux/io.h>  #include <linux/mutex.h>  #include <linux/spinlock.h> +#include <linux/export.h>  unsigned long PCIBIOS_MIN_IO = 0x0000;  unsigned long PCIBIOS_MIN_MEM = 0; @@ -31,19 +32,34 @@ static struct pci_channel *hose_head, **hose_tail = &hose_head;  static int pci_initialized; -static void __devinit pcibios_scanbus(struct pci_channel *hose) +static void pcibios_scanbus(struct pci_channel *hose)  {  	static int next_busno;  	static int need_domain_info; +	LIST_HEAD(resources); +	struct resource *res; +	resource_size_t offset; +	int i;  	struct pci_bus *bus; -	bus = pci_scan_bus(next_busno, hose->pci_ops, hose); +	for (i = 0; i < hose->nr_resources; i++) { +		res = hose->resources + i; +		offset = 0; +		if (res->flags & IORESOURCE_IO) +			offset = hose->io_offset; +		else if (res->flags & IORESOURCE_MEM) +			offset = hose->mem_offset; +		pci_add_resource_offset(&resources, res, offset); +	} + +	bus = pci_scan_root_bus(NULL, next_busno, hose->pci_ops, hose, +				&resources);  	hose->bus = bus;  	need_domain_info = need_domain_info || hose->index;  	hose->need_domain_info = need_domain_info;  	if (bus) { -		next_busno = bus->subordinate + 1; +		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) { @@ -53,7 +69,8 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)  		pci_bus_size_bridges(bus);  		pci_bus_assign_resources(bus); -		pci_enable_bridges(bus); +	} else { +		pci_free_resource_list(&resources);  	}  } @@ -64,7 +81,7 @@ static void __devinit pcibios_scanbus(struct pci_channel *hose)  DEFINE_RAW_SPINLOCK(pci_config_lock);  static DEFINE_MUTEX(pci_scan_mutex); -int __devinit register_pci_controller(struct pci_channel *hose) +int register_pci_controller(struct pci_channel *hose)  {  	int i; @@ -84,7 +101,7 @@ int __devinit register_pci_controller(struct pci_channel *hose)  	hose_tail = &hose->next;  	/* -	 * Do not panic here but later - this might hapen before console init. +	 * Do not panic here but later - this might happen before console init.  	 */  	if (!hose->io_map_base) {  		printk(KERN_WARNING @@ -134,50 +151,12 @@ static int __init pcibios_init(void)  }  subsys_initcall(pcibios_init); -static void pcibios_fixup_device_resources(struct pci_dev *dev, -	struct pci_bus *bus) -{ -	/* Update device resources.  */ -	struct pci_channel *hose = bus->sysdata; -	unsigned long offset = 0; -	int i; - -	for (i = 0; i < PCI_NUM_RESOURCES; i++) { -		if (!dev->resource[i].start) -			continue; -		if (dev->resource[i].flags & IORESOURCE_IO) -			offset = hose->io_offset; -		else if (dev->resource[i].flags & IORESOURCE_MEM) -			offset = hose->mem_offset; - -		dev->resource[i].start += offset; -		dev->resource[i].end += offset; -	} -} -  /*   *  Called after each bus is probed, but before its children   *  are examined.   */ -void __devinit pcibios_fixup_bus(struct pci_bus *bus) +void pcibios_fixup_bus(struct pci_bus *bus)  { -	struct pci_dev *dev = bus->self; -	struct list_head *ln; -	struct pci_channel *hose = bus->sysdata; - -	if (!dev) { -		int i; - -		for (i = 0; i < hose->nr_resources; i++) -			bus->resource[i] = hose->resources + i; -	} - -	for (ln = bus->devices.next; ln != &bus->devices; ln = ln->next) { -		dev = pci_dev_b(ln); - -		if ((dev->class >> 8) != PCI_CLASS_BRIDGE_PCI) -			pcibios_fixup_device_resources(dev, bus); -	}  }  /* @@ -207,72 +186,6 @@ resource_size_t pcibios_align_resource(void *data, const struct resource *res,  	return start;  } -void pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -			     struct resource *res) -{ -	struct pci_channel *hose = dev->sysdata; -	unsigned long offset = 0; - -	if (res->flags & IORESOURCE_IO) -		offset = hose->io_offset; -	else if (res->flags & IORESOURCE_MEM) -		offset = hose->mem_offset; - -	region->start = res->start - offset; -	region->end = res->end - offset; -} - -void pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -			     struct pci_bus_region *region) -{ -	struct pci_channel *hose = dev->sysdata; -	unsigned long offset = 0; - -	if (res->flags & IORESOURCE_IO) -		offset = hose->io_offset; -	else if (res->flags & IORESOURCE_MEM) -		offset = hose->mem_offset; - -	res->start = region->start + offset; -	res->end = region->end + offset; -} - -int pcibios_enable_device(struct pci_dev *dev, int mask) -{ -	return pci_enable_resources(dev, mask); -} - -/* - *  If we set up a device for bus mastering, we need to check and set - *  the latency timer as it may not be properly set. - */ -static unsigned int pcibios_max_latency = 255; - -void pcibios_set_master(struct pci_dev *dev) -{ -	u8 lat; -	pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); -	if (lat < 16) -		lat = (64 <= pcibios_max_latency) ? 64 : pcibios_max_latency; -	else if (lat > pcibios_max_latency) -		lat = pcibios_max_latency; -	else -		return; -	printk(KERN_INFO "PCI: Setting latency timer of device %s to %d\n", -	       pci_name(dev), lat); -	pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); -} - -void __init pcibios_update_irq(struct pci_dev *dev, int irq) -{ -	pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -} - -char * __devinit __weak pcibios_setup(char *str) -{ -	return str; -} -  static void __init  pcibios_bus_report_status_early(struct pci_channel *hose,  				int top_bus, int current_bus, @@ -376,46 +289,22 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma,  #ifndef CONFIG_GENERIC_IOMAP -static void __iomem *ioport_map_pci(struct pci_dev *dev, -				    unsigned long port, unsigned int nr) +void __iomem *__pci_ioport_map(struct pci_dev *dev, +			       unsigned long port, unsigned int nr)  {  	struct pci_channel *chan = dev->sysdata;  	if (unlikely(!chan->io_map_base)) { -		chan->io_map_base = generic_io_base; +		chan->io_map_base = sh_io_port_base;  		if (pci_domains_supported)  			panic("To avoid data corruption io_map_base MUST be "  			      "set with multiple PCI domains.");  	} -  	return (void __iomem *)(chan->io_map_base + port);  } -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ -	resource_size_t start = pci_resource_start(dev, bar); -	resource_size_t len = pci_resource_len(dev, bar); -	unsigned long flags = pci_resource_flags(dev, bar); - -	if (unlikely(!len || !start)) -		return NULL; -	if (maxlen && len > maxlen) -		len = maxlen; - -	if (flags & IORESOURCE_IO) -		return ioport_map_pci(dev, start, len); -	if (flags & IORESOURCE_MEM) { -		if (flags & IORESOURCE_CACHEABLE) -			return ioremap(start, len); -		return ioremap_nocache(start, len); -	} - -	return NULL; -} -EXPORT_SYMBOL(pci_iomap); -  void pci_iounmap(struct pci_dev *dev, void __iomem *addr)  {  	iounmap(addr); @@ -424,9 +313,5 @@ EXPORT_SYMBOL(pci_iounmap);  #endif /* CONFIG_GENERIC_IOMAP */ -#ifdef CONFIG_HOTPLUG -EXPORT_SYMBOL(pcibios_resource_to_bus); -EXPORT_SYMBOL(pcibios_bus_to_resource);  EXPORT_SYMBOL(PCIBIOS_MIN_IO);  EXPORT_SYMBOL(PCIBIOS_MIN_MEM); -#endif diff --git a/arch/sh/drivers/pci/pcie-sh7786.c b/arch/sh/drivers/pci/pcie-sh7786.c index 96e9b058aa1..a162a7f86b2 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.c +++ b/arch/sh/drivers/pci/pcie-sh7786.c @@ -1,20 +1,24 @@  /*   * Low-Level PCI Express Support for the SH7786   * - *  Copyright (C) 2009 - 2010  Paul Mundt + *  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 +  #include <linux/pci.h>  #include <linux/init.h>  #include <linux/kernel.h>  #include <linux/io.h> +#include <linux/async.h>  #include <linux/delay.h>  #include <linux/slab.h>  #include <linux/clk.h>  #include <linux/sh_clk.h> +#include <linux/sh_intc.h>  #include "pcie-sh7786.h"  #include <asm/sizes.h> @@ -31,7 +35,7 @@ static unsigned int nr_ports;  static struct sh7786_pcie_hwops {  	int (*core_init)(void); -	int (*port_init_hw)(struct sh7786_pcie_port *port); +	async_func_t port_init_hw;  } *sh7786_pcie_hwops;  static struct resource sh7786_pci0_resources[] = { @@ -128,7 +132,7 @@ static struct clk fixed_pciexclkp = {  	.rate = 100000000,	/* 100 MHz reference clock */  }; -static void __devinit sh7786_pci_fixup(struct pci_dev *dev) +static void sh7786_pci_fixup(struct pci_dev *dev)  {  	/*  	 * Prevent enumeration of root complex resources. @@ -235,7 +239,7 @@ static int __init pcie_clk_init(struct sh7786_pcie_port *port)  	clk->enable_reg = (void __iomem *)(chan->reg_base + SH4A_PCIEPHYCTLR);  	clk->enable_bit = BITS_CKE; -	ret = sh_clk_mstp32_register(clk, 1); +	ret = sh_clk_mstp_register(clk, 1);  	if (unlikely(ret < 0))  		goto err_phy; @@ -463,9 +467,9 @@ static int __init pcie_init(struct sh7786_pcie_port *port)  	return 0;  } -int __init pcibios_map_platform_irq(struct pci_dev *pdev, u8 slot, u8 pin) +int __init pcibios_map_platform_irq(const struct pci_dev *pdev, u8 slot, u8 pin)  { -        return 71; +        return evt2irq(0xae0);  }  static int __init sh7786_pcie_core_init(void) @@ -474,8 +478,9 @@ static int __init sh7786_pcie_core_init(void)  	return test_mode_pin(MODE_PIN12) ? 3 : 2;  } -static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port) +static void __init sh7786_pcie_init_hw(void *data, async_cookie_t cookie)  { +	struct sh7786_pcie_port *port = data;  	int ret;  	/* @@ -488,18 +493,30 @@ static int __init sh7786_pcie_init_hw(struct sh7786_pcie_port *port)  	 * Setup clocks, needed both for PHY and PCIe registers.  	 */  	ret = pcie_clk_init(port); -	if (unlikely(ret < 0)) -		return ret; +	if (unlikely(ret < 0)) { +		pr_err("clock initialization failed for port#%d\n", +		       port->index); +		return; +	}  	ret = phy_init(port); -	if (unlikely(ret < 0)) -		return ret; +	if (unlikely(ret < 0)) { +		pr_err("phy initialization failed for port#%d\n", +		       port->index); +		return; +	}  	ret = pcie_init(port); -	if (unlikely(ret < 0)) -		return ret; +	if (unlikely(ret < 0)) { +		pr_err("core initialization failed for port#%d\n", +			       port->index); +		return; +	} -	return register_pci_controller(port->hose); +	/* In the interest of preserving device ordering, synchronize */ +	async_synchronize_cookie(cookie); + +	register_pci_controller(port->hose);  }  static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = { @@ -510,7 +527,7 @@ static struct sh7786_pcie_hwops sh7786_65nm_pcie_hwops __initdata = {  static int __init sh7786_pcie_init(void)  {  	struct clk *platclk; -	int ret = 0, i; +	int i;  	printk(KERN_NOTICE "PCI: Starting initialization.\n"); @@ -552,14 +569,10 @@ static int __init sh7786_pcie_init(void)  		port->hose		= sh7786_pci_channels + i;  		port->hose->io_map_base	= port->hose->resources[0].start; -		ret |= sh7786_pcie_hwops->port_init_hw(port); +		async_schedule(sh7786_pcie_hwops->port_init_hw, port);  	} -	if (unlikely(ret)) { -		clk_disable(platclk); -		clk_put(platclk); -		return ret; -	} +	async_synchronize_full();  	return 0;  } diff --git a/arch/sh/drivers/pci/pcie-sh7786.h b/arch/sh/drivers/pci/pcie-sh7786.h index 1ee054e47ea..4a6ff55f759 100644 --- a/arch/sh/drivers/pci/pcie-sh7786.h +++ b/arch/sh/drivers/pci/pcie-sh7786.h @@ -145,9 +145,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/push-switch.c b/arch/sh/drivers/push-switch.c index 7b42c247316..5bfb341cc5c 100644 --- a/arch/sh/drivers/push-switch.c +++ b/arch/sh/drivers/push-switch.c @@ -63,7 +63,7 @@ static int switch_drv_probe(struct platform_device *pdev)  	BUG_ON(!psw_info);  	ret = request_irq(irq, psw_info->irq_handler, -			  IRQF_DISABLED | psw_info->irq_flags, +			  psw_info->irq_flags,  			  psw_info->name ? psw_info->name : DRV_NAME, pdev);  	if (unlikely(ret < 0))  		goto err; @@ -107,7 +107,7 @@ static int switch_drv_remove(struct platform_device *pdev)  		device_remove_file(&pdev->dev, &dev_attr_switch);  	platform_set_drvdata(pdev, NULL); -	flush_scheduled_work(); +	flush_work(&psw->work);  	del_timer_sync(&psw->debounce);  	free_irq(irq, pdev);  | 
