Skip to content

Commit

Permalink
Convert SGI IP22 and specific drivers to platform_device.
Browse files Browse the repository at this point in the history
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>
  • Loading branch information
ralfbaechle committed May 11, 2007
1 parent 129a84d commit df9f540
Show file tree
Hide file tree
Showing 6 changed files with 376 additions and 191 deletions.
2 changes: 1 addition & 1 deletion arch/mips/sgi-ip22/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@
#

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
177 changes: 177 additions & 0 deletions arch/mips/sgi-ip22/ip22-platform.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
#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);
83 changes: 37 additions & 46 deletions drivers/net/sgiseeq.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,13 @@
#include <linux/string.h>
#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/platform_device.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>

#include <asm/sgi/hpc3.h>
#include <asm/sgi/ip22.h>
#include <asm/sgi/seeq.h>

#include "sgiseeq.h"

Expand Down Expand Up @@ -92,13 +94,9 @@ struct sgiseeq_private {

struct net_device_stats stats;

struct net_device *next_module;
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)
{
hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
Expand Down Expand Up @@ -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))

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;
unsigned int irq = pd->irq;
struct sgiseeq_private *sp;
struct net_device *dev;
int err, i;
Expand All @@ -637,6 +638,8 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
err = -ENOMEM;
goto err_out;
}

platform_set_drvdata(pdev, dev);
sp = netdev_priv(dev);

/* Make private data page aligned */
Expand All @@ -648,15 +651,7 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
}
sp->srings = sr;

#define EADDR_NVOFS 250
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;
}
memcpy(dev->dev_addr, pd->mac, ETH_ALEN);

#ifdef DEBUG
gpriv = sp;
Expand Down Expand Up @@ -720,9 +715,6 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
for (i = 0; i < 6; i++)
printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');

sp->next_module = root_sgiseeq_dev;
root_sgiseeq_dev = dev;

return 0;

err_out_free_page:
Expand All @@ -734,43 +726,42 @@ static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq, int has_eeprom)
return err;
}

static int __init sgiseeq_probe(void)
static void __exit sgiseeq_remove(struct platform_device *pdev)
{
unsigned int tmp, ret1, ret2 = 0;

/* 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);
}
struct net_device *dev = platform_get_drvdata(pdev);
struct sgiseeq_private *sp = netdev_priv(dev);

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)
{
struct net_device *next, *dev;
struct sgiseeq_private *sp;
static struct platform_driver sgiseeq_driver = {
.probe = sgiseeq_probe,
.remove = __devexit_p(sgiseeq_remove),
.driver = {
.name = "sgiseeq"
}
};

for (dev = root_sgiseeq_dev; dev; dev = next) {
sp = (struct sgiseeq_private *) netdev_priv(dev);
next = sp->next_module;
unregister_netdev(dev);
free_page((unsigned long) sp->srings);
free_netdev(dev);
static int __init sgiseeq_module_init(void)
{
if (platform_driver_register(&sgiseeq_driver)) {
printk(KERN_ERR "Driver registration failed\n");
return -ENODEV;
}

return 0;
}

static void __exit sgiseeq_module_exit(void)
{
platform_driver_unregister(&sgiseeq_driver);
}

module_init(sgiseeq_probe);
module_exit(sgiseeq_exit);
module_init(sgiseeq_module_init);
module_exit(sgiseeq_module_exit);

MODULE_DESCRIPTION("SGI Seeq 8003 driver");
MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips@linux-mips.org>");
Expand Down
Loading

0 comments on commit df9f540

Please sign in to comment.