Commit 0c4ea957 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-ip22

* 'upstream' of git://ftp.linux-mips.org/pub/scm/upstream-ip22:
  Convert SGI IP22 and specific drivers to platform_device.
parents f2c60ed0 df9f5408
...@@ -4,6 +4,6 @@ ...@@ -4,6 +4,6 @@
# #
obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \ obj-y += ip22-mc.o ip22-hpc.o ip22-int.o ip22-berr.o \
ip22-time.o ip22-nvram.o ip22-reset.o ip22-setup.o ip22-time.o ip22-nvram.o ip22-platform.o ip22-reset.o ip22-setup.o
obj-$(CONFIG_EISA) += ip22-eisa.o obj-$(CONFIG_EISA) += ip22-eisa.o
#include <linux/init.h>
#include <linux/if_ether.h>
#include <linux/kernel.h>
#include <linux/platform_device.h>
#include <asm/paccess.h>
#include <asm/sgi/ip22.h>
#include <asm/sgi/hpc3.h>
#include <asm/sgi/mc.h>
#include <asm/sgi/seeq.h>
#include <asm/sgi/wd.h>
static struct resource sgiwd93_0_resources[] = {
{
.name = "eth0 irq",
.start = SGI_WD93_0_IRQ,
.end = SGI_WD93_0_IRQ,
.flags = IORESOURCE_IRQ
}
};
static struct sgiwd93_platform_data sgiwd93_0_pd = {
.unit = 0,
.irq = SGI_WD93_0_IRQ,
};
static struct platform_device sgiwd93_0_device = {
.name = "sgiwd93",
.id = 0,
.num_resources = ARRAY_SIZE(sgiwd93_0_resources),
.resource = sgiwd93_0_resources,
.dev = {
.platform_data = &sgiwd93_0_pd,
},
};
static struct resource sgiwd93_1_resources[] = {
{
.name = "eth0 irq",
.start = SGI_WD93_1_IRQ,
.end = SGI_WD93_1_IRQ,
.flags = IORESOURCE_IRQ
}
};
static struct sgiwd93_platform_data sgiwd93_1_pd = {
.unit = 1,
.irq = SGI_WD93_1_IRQ,
};
static struct platform_device sgiwd93_1_device = {
.name = "sgiwd93",
.id = 1,
.num_resources = ARRAY_SIZE(sgiwd93_1_resources),
.resource = sgiwd93_1_resources,
.dev = {
.platform_data = &sgiwd93_1_pd,
},
};
/*
* Create a platform device for the GPI port that receives the
* image data from the embedded camera.
*/
static int __init sgiwd93_devinit(void)
{
int res;
sgiwd93_0_pd.hregs = &hpc3c0->scsi_chan0;
sgiwd93_0_pd.wdregs = (unsigned char *) hpc3c0->scsi0_ext;
res = platform_device_register(&sgiwd93_0_device);
if (res)
return res;
if (!ip22_is_fullhouse())
return 0;
sgiwd93_1_pd.hregs = &hpc3c0->scsi_chan1;
sgiwd93_1_pd.wdregs = (unsigned char *) hpc3c0->scsi1_ext;
return platform_device_register(&sgiwd93_1_device);
}
device_initcall(sgiwd93_devinit);
static struct resource sgiseeq_0_resources[] = {
{
.name = "eth0 irq",
.start = SGI_ENET_IRQ,
.end = SGI_ENET_IRQ,
.flags = IORESOURCE_IRQ
}
};
static struct sgiseeq_platform_data eth0_pd;
static struct platform_device eth0_device = {
.name = "sgiseeq",
.id = 0,
.num_resources = ARRAY_SIZE(sgiseeq_0_resources),
.resource = sgiseeq_0_resources,
.dev = {
.platform_data = &eth0_pd,
},
};
static struct resource sgiseeq_1_resources[] = {
{
.name = "eth1 irq",
.start = SGI_GIO_0_IRQ,
.end = SGI_GIO_0_IRQ,
.flags = IORESOURCE_IRQ
}
};
static struct sgiseeq_platform_data eth1_pd;
static struct platform_device eth1_device = {
.name = "sgiseeq",
.id = 1,
.num_resources = ARRAY_SIZE(sgiseeq_1_resources),
.resource = sgiseeq_1_resources,
.dev = {
.platform_data = &eth1_pd,
},
};
/*
* Create a platform device for the GPI port that receives the
* image data from the embedded camera.
*/
static int __init sgiseeq_devinit(void)
{
unsigned int tmp;
int res, i;
eth0_pd.hpc = hpc3c0;
eth0_pd.irq = SGI_ENET_IRQ;
#define EADDR_NVOFS 250
for (i = 0; i < 3; i++) {
unsigned short tmp = ip22_nvram_read(EADDR_NVOFS / 2 + i);
eth0_pd.mac[2 * i] = tmp >> 8;
eth0_pd.mac[2 * i + 1] = tmp & 0xff;
}
res = platform_device_register(&eth0_device);
if (res)
return res;
/* Second HPC is missing? */
if (ip22_is_fullhouse() ||
!get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]))
return 0;
sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 | SGIMC_GIOPAR_EXP164 |
SGIMC_GIOPAR_HPC264;
hpc3c1->pbus_piocfg[0][0] = 0x3ffff;
/* interrupt/config register on Challenge S Mezz board */
hpc3c1->pbus_extregs[0][0] = 0x30;
eth1_pd.hpc = hpc3c1;
eth1_pd.irq = SGI_GIO_0_IRQ;
#define EADDR_NVOFS 250
for (i = 0; i < 3; i++) {
unsigned short tmp = ip22_eeprom_read(&hpc3c1->eeprom,
EADDR_NVOFS / 2 + i);
eth1_pd.mac[2 * i] = tmp >> 8;
eth1_pd.mac[2 * i + 1] = tmp & 0xff;
}
return platform_device_register(&eth1_device);
}
device_initcall(sgiseeq_devinit);
...@@ -16,11 +16,13 @@ ...@@ -16,11 +16,13 @@
#include <linux/string.h> #include <linux/string.h>
#include <linux/delay.h> #include <linux/delay.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/etherdevice.h> #include <linux/etherdevice.h>
#include <linux/skbuff.h> #include <linux/skbuff.h>
#include <asm/sgi/hpc3.h> #include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h> #include <asm/sgi/ip22.h>
#include <asm/sgi/seeq.h>
#include "sgiseeq.h" #include "sgiseeq.h"
...@@ -92,13 +94,9 @@ struct sgiseeq_private { ...@@ -92,13 +94,9 @@ struct sgiseeq_private {
struct net_device_stats stats; struct net_device_stats stats;
struct net_device *next_module;
spinlock_t tx_lock; spinlock_t tx_lock;
}; };
/* A list of all installed seeq devices, for removing the driver module. */
static struct net_device *root_sgiseeq_dev;
static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs) static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
{ {
hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ; hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
...@@ -624,9 +622,12 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs) ...@@ -624,9 +622,12 @@ static inline void setup_rx_ring(struct sgiseeq_rx_desc *buf, int nbufs)
#define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf)) #define ALIGNED(x) ((((unsigned long)(x)) + 0xf) & ~(0xf))
static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) static int __init sgiseeq_probe(struct platform_device *pdev)
{ {
struct sgiseeq_platform_data *pd = pdev->dev.platform_data;
struct hpc3_regs *hpcregs = pd->hpc;
struct sgiseeq_init_block *sr; struct sgiseeq_init_block *sr;
unsigned int irq = pd->irq;
struct sgiseeq_private *sp; struct sgiseeq_private *sp;
struct net_device *dev; struct net_device *dev;
int err, i; int err, i;
...@@ -637,6 +638,8 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) ...@@ -637,6 +638,8 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
err = -ENOMEM; err = -ENOMEM;
goto err_out; goto err_out;
} }
platform_set_drvdata(pdev, dev);
sp = netdev_priv(dev); sp = netdev_priv(dev);
/* Make private data page aligned */ /* Make private data page aligned */
...@@ -648,15 +651,7 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) ...@@ -648,15 +651,7 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
} }
sp->srings = sr; sp->srings = sr;
#define EADDR_NVOFS 250 memcpy(dev->dev_addr, pd->mac, ETH_ALEN);
for (i = 0; i < 3; i++) {
unsigned short tmp = has_eeprom ?
ip22_eeprom_read(&hpcregs->eeprom, EADDR_NVOFS / 2+i) :
ip22_nvram_read(EADDR_NVOFS / 2+i);
dev->dev_addr[2 * i] = tmp >> 8;
dev->dev_addr[2 * i + 1] = tmp & 0xff;
}
#ifdef DEBUG #ifdef DEBUG
gpriv = sp; gpriv = sp;
...@@ -720,9 +715,6 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) ...@@ -720,9 +715,6 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':'); printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
sp->next_module = root_sgiseeq_dev;
root_sgiseeq_dev = dev;
return 0; return 0;
err_out_free_page: err_out_free_page:
...@@ -734,43 +726,42 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom) ...@@ -734,43 +726,42 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
return err; return err;
} }
static int __init sgiseeq_probe(void) static void __exit sgiseeq_remove(struct platform_device *pdev)
{ {
unsigned int tmp, ret1, ret2 = 0; struct net_device *dev = platform_get_drvdata(pdev);
struct sgiseeq_private *sp = netdev_priv(dev);
/* On board adapter on 1st HPC is always present */
ret1 = sgiseeq_init(hpc3c0, SGI_ENET_IRQ, 0);
/* Let's see if second HPC is there */
if (!(ip22_is_fullhouse()) &&
get_dbe(tmp, (unsigned int *)&hpc3c1->pbdma[1]) == 0) {
sgimc->giopar |= SGIMC_GIOPAR_MASTEREXP1 |
SGIMC_GIOPAR_EXP164 |
SGIMC_GIOPAR_HPC264;
hpc3c1->pbus_piocfg[0][0] = 0x3ffff;
/* interrupt/config register on Challenge S Mezz board */
hpc3c1->pbus_extregs[0][0] = 0x30;
ret2 = sgiseeq_init(hpc3c1, SGI_GIO_0_IRQ, 1);
}
return (ret1 & ret2) ? ret1 : 0; unregister_netdev(dev);
free_page((unsigned long) sp->srings);
free_netdev(dev);
platform_set_drvdata(pdev, NULL);
} }
static void __exit sgiseeq_exit(void) static struct platform_driver sgiseeq_driver = {
{ .probe = sgiseeq_probe,
struct net_device *next, *dev; .remove = __devexit_p(sgiseeq_remove),
struct sgiseeq_private *sp; .driver = {
.name = "sgiseeq"
}
};
for (dev = root_sgiseeq_dev; dev; dev = next) { static int __init sgiseeq_module_init(void)
sp = (struct sgiseeq_private *) netdev_priv(dev); {
next = sp->next_module; if (platform_driver_register(&sgiseeq_driver)) {
unregister_netdev(dev); printk(KERN_ERR "Driver registration failed\n");
free_page((unsigned long) sp->srings); return -ENODEV;
free_netdev(dev);
} }
return 0;
}
static void __exit sgiseeq_module_exit(void)
{
platform_driver_unregister(&sgiseeq_driver);
} }
module_init(sgiseeq_probe); module_init(sgiseeq_module_init);
module_exit(sgiseeq_exit); module_exit(sgiseeq_module_exit);
MODULE_DESCRIPTION("SGI Seeq 8003 driver"); MODULE_DESCRIPTION("SGI Seeq 8003 driver");
MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>"); MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>");
......
This diff is collapsed.
/*
* 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.
*
* Copyright (C) 2007 by Ralf Baechle
*/
#ifndef __ASM_SGI_SEEQ_H
#define __ASM_SGI_SEEQ_H
#include <linux/if_ether.h>
#include <asm/sgi/hpc3.h>
struct sgiseeq_platform_data {
struct hpc3_regs *hpc;
unsigned int irq;
unsigned char mac[ETH_ALEN];
};
#endif /* __ASM_SGI_SEEQ_H */
/*
* 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.
*
* Copyright (C) 2007 by Ralf Baechle
*/
#ifndef __ASM_SGI_WD_H
#define __ASM_SGI_WD_H
#include <asm/sgi/hpc3.h>
struct sgiwd93_platform_data {
unsigned int unit;
unsigned int irq;
struct hpc3_scsiregs *hregs;
unsigned char *wdregs;
};
#endif /* __ASM_SGI_WD_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment