* [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs
@ 2007-03-16 16:25 Atsushi Nemoto
2007-05-09 15:03 ` Atsushi Nemoto
0 siblings, 1 reply; 5+ messages in thread
From: Atsushi Nemoto @ 2007-03-16 16:25 UTC (permalink / raw)
To: linux-mips; +Cc: ralf, sshtylyov
* Fix pci ops for secondary PCIC
* Do not reserve 1MB for PCI MEM region (leave PCIBIOS_MIN_MEM zero)
* Use NETDEV_REGISTER event to provide ethernet addresses for internal
NICs (tc35815 driver)
* Check return value of early_read_config_word()
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
---
arch/mips/pci/ops-tx4938.c | 60 ++++++++++++++++------------
arch/mips/tx4938/toshiba_rbtx4938/setup.c | 56 ++++++++++++++++----------
2 files changed, 72 insertions(+), 44 deletions(-)
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
index 4450070..db435bf 100644
--- a/arch/mips/pci/ops-tx4938.c
+++ b/arch/mips/pci/ops-tx4938.c
@@ -46,50 +46,61 @@ struct resource tx4938_pcic1_pci_mem_res
.flags = IORESOURCE_MEM
};
-static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+static int mkaddr(int bus, int dev_fn, int where,
+ struct tx4938_pcic_reg *pcicptr)
{
if (bus > 0) {
/* Type 1 configuration */
- tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
} else {
if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
return -1;
/* Type 0 configuration */
- tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
((dev_fn & 0xff) << 0x08) | (where & 0xfc);
}
/* clear M_ABORT and Disable M_ABORT Int. */
- tx4938_pcicptr->pcistatus =
- (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+ pcicptr->pcistatus =
+ (pcicptr->pcistatus & 0x0000ffff) |
(PCI_STATUS_REC_MASTER_ABORT << 16);
- tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+ pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
return 0;
}
-static int check_abort(int flags)
+static int check_abort(struct tx4938_pcic_reg *pcicptr)
{
int code = PCIBIOS_SUCCESSFUL;
/* wait write cycle completion before checking error status */
- while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+ while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
;
- if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
- tx4938_pcicptr->pcistatus =
- (tx4938_pcicptr->
+ if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+ pcicptr->pcistatus =
+ (pcicptr->
pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
<< 16);
- tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+ pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
code = PCIBIOS_DEVICE_NOT_FOUND;
}
return code;
}
+extern struct pci_controller tx4938_pci_controller[];
+extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch);
+
+static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus)
+{
+ struct pci_controller *channel = bus->sysdata;
+ return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]);
+}
+
static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 * val)
{
- int flags, retval, dev, busno, func;
+ int retval, dev, busno, func;
+ struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
dev = PCI_SLOT(devfn);
func = PCI_FUNC(devfn);
@@ -101,12 +112,12 @@ static int tx4938_pcibios_read_config(st
busno = 0;
}
- if (mkaddr(busno, devfn, where, &flags))
+ if (mkaddr(busno, devfn, where, pcicptr))
return -1;
switch (size) {
case 1:
- *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
+ *val = *(volatile u8 *) ((unsigned long) & pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
((where & 3) ^ 3));
#else
@@ -114,7 +125,7 @@ static int tx4938_pcibios_read_config(st
#endif
break;
case 2:
- *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
+ *val = *(volatile u16 *) ((unsigned long) & pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
((where & 3) ^ 2));
#else
@@ -122,11 +133,11 @@ static int tx4938_pcibios_read_config(st
#endif
break;
case 4:
- *val = tx4938_pcicptr->g2pcfgdata;
+ *val = pcicptr->g2pcfgdata;
break;
}
- retval = check_abort(flags);
+ retval = check_abort(pcicptr);
if (retval == PCIBIOS_DEVICE_NOT_FOUND)
*val = 0xffffffff;
@@ -136,7 +147,8 @@ static int tx4938_pcibios_read_config(st
static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 val)
{
- int flags, dev, busno, func;
+ int dev, busno, func;
+ struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
busno = bus->number;
dev = PCI_SLOT(devfn);
@@ -149,12 +161,12 @@ static int tx4938_pcibios_write_config(s
busno = 0;
}
- if (mkaddr(busno, devfn, where, &flags))
+ if (mkaddr(busno, devfn, where, pcicptr))
return -1;
switch (size) {
case 1:
- *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
+ *(volatile u8 *) ((unsigned long) & pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
((where & 3) ^ 3)) = val;
#else
@@ -162,7 +174,7 @@ static int tx4938_pcibios_write_config(s
#endif
break;
case 2:
- *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
+ *(volatile u16 *) ((unsigned long) & pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
((where & 0x3) ^ 0x2)) = val;
#else
@@ -170,11 +182,11 @@ static int tx4938_pcibios_write_config(s
#endif
break;
case 4:
- tx4938_pcicptr->g2pcfgdata = val;
+ pcicptr->g2pcfgdata = val;
break;
}
- return check_abort(flags);
+ return check_abort(pcicptr);
}
struct pci_ops tx4938_pci_ops = {
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 66163ba..9446dc9 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -20,6 +20,7 @@
#include <linux/console.h>
#include <linux/pci.h>
#include <linux/pm.h>
+#include <linux/netdevice.h>
#include <asm/wbflush.h>
#include <asm/reboot.h>
@@ -348,7 +349,7 @@ static struct pci_dev *fake_pci_dev(stru
static struct pci_dev dev;
static struct pci_bus bus;
- dev.sysdata = (void *)hose;
+ dev.sysdata = bus.sysdata = hose;
dev.devfn = devfn;
bus.number = busnr;
bus.ops = hose->pci_ops;
@@ -381,8 +382,10 @@ int txboard_pci66_check(struct pci_contr
printk("PCI: Checking 66MHz capabilities...\n");
for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
- early_read_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_VENDOR_ID, &vid);
+ if (early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_VENDOR_ID,
+ &vid) != PCIBIOS_SUCCESSFUL)
+ continue;
if (vid == 0xffff) continue;
@@ -459,7 +462,6 @@ static int __init tx4938_pcibios_init(vo
int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
PCIBIOS_MIN_IO = 0x00001000UL;
- PCIBIOS_MIN_MEM = 0x01000000UL;
mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
@@ -606,26 +608,11 @@ static int rbtx4938_spi_cs_func(int chip
#ifdef CONFIG_PCI
extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
-int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
+static int rbtx4938_get_tx4938_ethaddr(int ch, unsigned char *addr)
{
- struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
static unsigned char dat[17];
static int read_dat = 0;
- int ch = 0;
- if (channel != &tx4938_pci_controller[1])
- return -ENODEV;
- /* TX4938 PCIC1 */
- switch (PCI_SLOT(dev->devfn)) {
- case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
- ch = 0;
- break;
- case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
- ch = 1;
- break;
- default:
- return -ENODEV;
- }
if (!read_dat) {
unsigned char sum;
int i;
@@ -646,6 +633,35 @@ int rbtx4938_get_tx4938_ethaddr(struct p
memcpy(addr, &dat[4 + 6 * ch], 6);
return 0;
}
+
+static int rbtx4938_netdev_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+ struct net_device *dev = (struct net_device *)ptr;
+ if (event == NETDEV_REGISTER) {
+ int ch = -1;
+ if (dev->irq == RBTX4938_IRQ_IRC + TX4938_IR_ETH0)
+ ch = 0;
+ else if (dev->irq == RBTX4938_IRQ_IRC + TX4938_IR_ETH1)
+ ch = 1;
+ if (ch >= 0)
+ rbtx4938_get_tx4938_ethaddr(ch, dev->dev_addr);
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block rbtx4938_netdev_notifier = {
+ .notifier_call = rbtx4938_netdev_event,
+};
+
+static int __init rbtx4938_setup_eth(void)
+{
+ if (tx4938_ccfgptr->pcfg & (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL))
+ register_netdevice_notifier(&rbtx4938_netdev_notifier);
+ return 0;
+}
+device_initcall(rbtx4938_setup_eth);
#endif /* CONFIG_PCI */
extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs
2007-03-16 16:25 Atsushi Nemoto
@ 2007-05-09 15:03 ` Atsushi Nemoto
0 siblings, 0 replies; 5+ messages in thread
From: Atsushi Nemoto @ 2007-05-09 15:03 UTC (permalink / raw)
To: linux-mips; +Cc: ralf, sshtylyov
On Sat, 17 Mar 2007 01:25:39 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> wrote:
> * Fix pci ops for secondary PCIC
> * Do not reserve 1MB for PCI MEM region (leave PCIBIOS_MIN_MEM zero)
> * Use NETDEV_REGISTER event to provide ethernet addresses for internal
> NICs (tc35815 driver)
> * Check return value of early_read_config_word()
Updated against current git tree.
Subject: [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs
* Fix pci ops for secondary PCIC
* Do not reserve 1MB for PCI MEM region (leave PCIBIOS_MIN_MEM zero)
* Use NETDEV_REGISTER event to provide ethernet addresses for internal
NICs (tc35815 driver)
* Check return value of early_read_config_word()
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
---
arch/mips/pci/ops-tx4938.c | 60 +++++++++++++++++-----------
arch/mips/tx4938/toshiba_rbtx4938/setup.c | 56 +++++++++++++++++----------
2 files changed, 72 insertions(+), 44 deletions(-)
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
index 4450070..db435bf 100644
--- a/arch/mips/pci/ops-tx4938.c
+++ b/arch/mips/pci/ops-tx4938.c
@@ -46,50 +46,61 @@ struct resource tx4938_pcic1_pci_mem_resource = {
.flags = IORESOURCE_MEM
};
-static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+static int mkaddr(int bus, int dev_fn, int where,
+ struct tx4938_pcic_reg *pcicptr)
{
if (bus > 0) {
/* Type 1 configuration */
- tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
} else {
if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
return -1;
/* Type 0 configuration */
- tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
((dev_fn & 0xff) << 0x08) | (where & 0xfc);
}
/* clear M_ABORT and Disable M_ABORT Int. */
- tx4938_pcicptr->pcistatus =
- (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+ pcicptr->pcistatus =
+ (pcicptr->pcistatus & 0x0000ffff) |
(PCI_STATUS_REC_MASTER_ABORT << 16);
- tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+ pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
return 0;
}
-static int check_abort(int flags)
+static int check_abort(struct tx4938_pcic_reg *pcicptr)
{
int code = PCIBIOS_SUCCESSFUL;
/* wait write cycle completion before checking error status */
- while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+ while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
;
- if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
- tx4938_pcicptr->pcistatus =
- (tx4938_pcicptr->
+ if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+ pcicptr->pcistatus =
+ (pcicptr->
pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
<< 16);
- tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+ pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
code = PCIBIOS_DEVICE_NOT_FOUND;
}
return code;
}
+extern struct pci_controller tx4938_pci_controller[];
+extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch);
+
+static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus)
+{
+ struct pci_controller *channel = bus->sysdata;
+ return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]);
+}
+
static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 * val)
{
- int flags, retval, dev, busno, func;
+ int retval, dev, busno, func;
+ struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
dev = PCI_SLOT(devfn);
func = PCI_FUNC(devfn);
@@ -101,12 +112,12 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
busno = 0;
}
- if (mkaddr(busno, devfn, where, &flags))
+ if (mkaddr(busno, devfn, where, pcicptr))
return -1;
switch (size) {
case 1:
- *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
+ *val = *(volatile u8 *) ((unsigned long) & pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
((where & 3) ^ 3));
#else
@@ -114,7 +125,7 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
#endif
break;
case 2:
- *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
+ *val = *(volatile u16 *) ((unsigned long) & pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
((where & 3) ^ 2));
#else
@@ -122,11 +133,11 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
#endif
break;
case 4:
- *val = tx4938_pcicptr->g2pcfgdata;
+ *val = pcicptr->g2pcfgdata;
break;
}
- retval = check_abort(flags);
+ retval = check_abort(pcicptr);
if (retval == PCIBIOS_DEVICE_NOT_FOUND)
*val = 0xffffffff;
@@ -136,7 +147,8 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 val)
{
- int flags, dev, busno, func;
+ int dev, busno, func;
+ struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
busno = bus->number;
dev = PCI_SLOT(devfn);
@@ -149,12 +161,12 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn,
busno = 0;
}
- if (mkaddr(busno, devfn, where, &flags))
+ if (mkaddr(busno, devfn, where, pcicptr))
return -1;
switch (size) {
case 1:
- *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
+ *(volatile u8 *) ((unsigned long) & pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
((where & 3) ^ 3)) = val;
#else
@@ -162,7 +174,7 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn,
#endif
break;
case 2:
- *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
+ *(volatile u16 *) ((unsigned long) & pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
((where & 0x3) ^ 0x2)) = val;
#else
@@ -170,11 +182,11 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn,
#endif
break;
case 4:
- tx4938_pcicptr->g2pcfgdata = val;
+ pcicptr->g2pcfgdata = val;
break;
}
- return check_abort(flags);
+ return check_abort(pcicptr);
}
struct pci_ops tx4938_pci_ops = {
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index f5d1ce7..4e26673 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -21,6 +21,7 @@
#include <linux/pci.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
+#include <linux/netdevice.h>
#include <asm/wbflush.h>
#include <asm/reboot.h>
@@ -349,7 +350,7 @@ static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
static struct pci_dev dev;
static struct pci_bus bus;
- dev.sysdata = (void *)hose;
+ dev.sysdata = bus.sysdata = hose;
dev.devfn = devfn;
bus.number = busnr;
bus.ops = hose->pci_ops;
@@ -382,8 +383,10 @@ int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bu
printk("PCI: Checking 66MHz capabilities...\n");
for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
- early_read_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_VENDOR_ID, &vid);
+ if (early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_VENDOR_ID,
+ &vid) != PCIBIOS_SUCCESSFUL)
+ continue;
if (vid == 0xffff) continue;
@@ -460,7 +463,6 @@ static int __init tx4938_pcibios_init(void)
int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
PCIBIOS_MIN_IO = 0x00001000UL;
- PCIBIOS_MIN_MEM = 0x01000000UL;
mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
@@ -607,26 +609,11 @@ static int rbtx4938_spi_cs_func(int chipid, int on)
#ifdef CONFIG_PCI
extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len);
-int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
+static int rbtx4938_get_tx4938_ethaddr(int ch, unsigned char *addr)
{
- struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
static unsigned char dat[17];
static int read_dat = 0;
- int ch = 0;
- if (channel != &tx4938_pci_controller[1])
- return -ENODEV;
- /* TX4938 PCIC1 */
- switch (PCI_SLOT(dev->devfn)) {
- case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
- ch = 0;
- break;
- case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
- ch = 1;
- break;
- default:
- return -ENODEV;
- }
if (!read_dat) {
unsigned char sum;
int i;
@@ -647,6 +634,35 @@ int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
memcpy(addr, &dat[4 + 6 * ch], 6);
return 0;
}
+
+static int rbtx4938_netdev_event(struct notifier_block *this,
+ unsigned long event,
+ void *ptr)
+{
+ struct net_device *dev = ptr;
+ if (event == NETDEV_REGISTER) {
+ int ch = -1;
+ if (dev->irq == RBTX4938_IRQ_IRC + TX4938_IR_ETH0)
+ ch = 0;
+ else if (dev->irq == RBTX4938_IRQ_IRC + TX4938_IR_ETH1)
+ ch = 1;
+ if (ch >= 0)
+ rbtx4938_get_tx4938_ethaddr(ch, dev->dev_addr);
+ }
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block rbtx4938_netdev_notifier = {
+ .notifier_call = rbtx4938_netdev_event,
+};
+
+static int __init rbtx4938_setup_eth(void)
+{
+ if (tx4938_ccfgptr->pcfg & (TX4938_PCFG_ETH0_SEL|TX4938_PCFG_ETH1_SEL))
+ register_netdevice_notifier(&rbtx4938_netdev_notifier);
+ return 0;
+}
+device_initcall(rbtx4938_setup_eth);
#endif /* CONFIG_PCI */
extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on));
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs
@ 2007-06-29 13:35 Atsushi Nemoto
2007-07-02 13:43 ` Atsushi Nemoto
0 siblings, 1 reply; 5+ messages in thread
From: Atsushi Nemoto @ 2007-06-29 13:35 UTC (permalink / raw)
To: linux-mips; +Cc: ralf, sshtylyov, mlachwani, jeff
* Fix pci ops for secondary PCIC
* Do not reserve 1MB for PCI MEM region (leave PCIBIOS_MIN_MEM zero)
* Use platform_device to provide ethernet addresses for internal NICs.
(background: TX49XX SoCs include PCI NIC (TC35815 compatible)
connected via its internal PCI bus, but the NIC's PROM interface is
not connected to SEEPROM. So we must provide its ethernet address
by another way.)
* Check return value of early_read_config_word()
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
---
A driver side of this patch is:
"[PATCH] tc35815: Load MAC address via platform_device"
arch/mips/pci/ops-tx4938.c | 80 +++++++++++++++++-----------
arch/mips/tx4938/toshiba_rbtx4938/setup.c | 54 ++++++++-----------
2 files changed, 71 insertions(+), 63 deletions(-)
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
index 4450070..a450c40 100644
--- a/arch/mips/pci/ops-tx4938.c
+++ b/arch/mips/pci/ops-tx4938.c
@@ -46,50 +46,63 @@ struct resource tx4938_pcic1_pci_mem_resource = {
.flags = IORESOURCE_MEM
};
-static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+static int mkaddr(int bus, int dev_fn, int where,
+ struct tx4938_pcic_reg *pcicptr)
{
if (bus > 0) {
/* Type 1 configuration */
- tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
} else {
if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
return -1;
/* Type 0 configuration */
- tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
((dev_fn & 0xff) << 0x08) | (where & 0xfc);
}
/* clear M_ABORT and Disable M_ABORT Int. */
- tx4938_pcicptr->pcistatus =
- (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+ pcicptr->pcistatus =
+ (pcicptr->pcistatus & 0x0000ffff) |
(PCI_STATUS_REC_MASTER_ABORT << 16);
- tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+ pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
return 0;
}
-static int check_abort(int flags)
+static int check_abort(struct tx4938_pcic_reg *pcicptr)
{
int code = PCIBIOS_SUCCESSFUL;
/* wait write cycle completion before checking error status */
- while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+ while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
;
- if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
- tx4938_pcicptr->pcistatus =
- (tx4938_pcicptr->
+ if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+ pcicptr->pcistatus =
+ (pcicptr->
pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
<< 16);
- tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+ pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
code = PCIBIOS_DEVICE_NOT_FOUND;
}
return code;
}
+extern struct pci_controller tx4938_pci_controller[];
+extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch);
+
+static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus)
+{
+ struct pci_controller *channel = bus->sysdata;
+ return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]);
+}
+
static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 * val)
{
- int flags, retval, dev, busno, func;
+ int retval, dev, busno, func;
+ struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
+ void __iomem *cfgdata =
+ (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
dev = PCI_SLOT(devfn);
func = PCI_FUNC(devfn);
@@ -101,32 +114,32 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
busno = 0;
}
- if (mkaddr(busno, devfn, where, &flags))
+ if (mkaddr(busno, devfn, where, pcicptr))
return -1;
switch (size) {
case 1:
- *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
- ((where & 3) ^ 3));
+ cfgdata += (where & 3) ^ 3;
#else
- (where & 3));
+ cfgdata += where & 3;
#endif
+ *val = __raw_readb(cfgdata);
break;
case 2:
- *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
- ((where & 3) ^ 2));
+ cfgdata += (where & 2) ^ 2;
#else
- (where & 3));
+ cfgdata += where & 2;
#endif
+ *val = __raw_readw(cfgdata);
break;
case 4:
- *val = tx4938_pcicptr->g2pcfgdata;
+ *val = __raw_readl(cfgdata);
break;
}
- retval = check_abort(flags);
+ retval = check_abort(pcicptr);
if (retval == PCIBIOS_DEVICE_NOT_FOUND)
*val = 0xffffffff;
@@ -136,7 +149,10 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 val)
{
- int flags, dev, busno, func;
+ int dev, busno, func;
+ struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
+ void __iomem *cfgdata =
+ (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
busno = bus->number;
dev = PCI_SLOT(devfn);
@@ -149,32 +165,32 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn,
busno = 0;
}
- if (mkaddr(busno, devfn, where, &flags))
+ if (mkaddr(busno, devfn, where, pcicptr))
return -1;
switch (size) {
case 1:
- *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
- ((where & 3) ^ 3)) = val;
+ cfgdata += (where & 3) ^ 3;
#else
- (where & 3)) = val;
+ cfgdata += where & 3;
#endif
+ __raw_writeb(val, cfgdata);
break;
case 2:
- *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
- ((where & 0x3) ^ 0x2)) = val;
+ cfgdata += (where & 2) ^ 2;
#else
- (where & 3)) = val;
+ cfgdata += where & 2;
#endif
+ __raw_writew(val, cfgdata);
break;
case 4:
- tx4938_pcicptr->g2pcfgdata = val;
+ __raw_writel(val, cfgdata);
break;
}
- return check_abort(flags);
+ return check_abort(pcicptr);
}
struct pci_ops tx4938_pci_ops = {
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 361d89a..d9fbf51 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -352,7 +352,7 @@ static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
static struct pci_dev dev;
static struct pci_bus bus;
- dev.sysdata = (void *)hose;
+ dev.sysdata = bus.sysdata = hose;
dev.devfn = devfn;
bus.number = busnr;
bus.ops = hose->pci_ops;
@@ -385,8 +385,10 @@ int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bu
printk("PCI: Checking 66MHz capabilities...\n");
for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
- early_read_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_VENDOR_ID, &vid);
+ if (early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_VENDOR_ID,
+ &vid) != PCIBIOS_SUCCESSFUL)
+ continue;
if (vid == 0xffff) continue;
@@ -463,7 +465,6 @@ static int __init tx4938_pcibios_init(void)
int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
PCIBIOS_MIN_IO = 0x00001000UL;
- PCIBIOS_MIN_MEM = 0x01000000UL;
mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
@@ -578,18 +579,18 @@ arch_initcall(tx4938_pcibios_init);
#define SRTC_CS 2 /* IOC */
#ifdef CONFIG_PCI
-static unsigned char rbtx4938_ethaddr[17];
static int __init rbtx4938_ethaddr_init(void)
{
+ unsigned char ethaddr[17];
unsigned char sum;
int i;
/* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
- if (spi_eeprom_read(SEEPROM1_CS, 0,
- rbtx4938_ethaddr, sizeof(rbtx4938_ethaddr)))
+ if (spi_eeprom_read(SEEPROM1_CS, 0, ethaddr, sizeof(ethaddr))) {
printk(KERN_ERR "seeprom: read error.\n");
- else {
- unsigned char *dat = rbtx4938_ethaddr;
+ return -ENODEV;
+ } else {
+ unsigned char *dat = ethaddr;
if (strcmp(dat, "MAC") != 0)
printk(KERN_WARNING "seeprom: bad signature.\n");
for (i = 0, sum = 0; i < sizeof(dat); i++)
@@ -597,31 +598,22 @@ static int __init rbtx4938_ethaddr_init(void)
if (sum)
printk(KERN_WARNING "seeprom: bad checksum.\n");
}
- return 0;
-}
-device_initcall(rbtx4938_ethaddr_init);
-
-int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
-{
- struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
- int ch = 0;
-
- if (channel != &tx4938_pci_controller[1])
- return -ENODEV;
- /* TX4938 PCIC1 */
- switch (PCI_SLOT(dev->devfn)) {
- case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
- ch = 0;
- break;
- case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
- ch = 1;
- break;
- default:
- return -ENODEV;
+ for (i = 0; i < 2; i++) {
+ unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i);
+ unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */
+ struct platform_device *pdev;
+ if (!(tx4938_ccfgptr->pcfg &
+ (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
+ continue;
+ pdev = platform_device_alloc("tc35815-mac", id);
+ if (!pdev ||
+ platform_device_add_data(pdev, ðaddr[4 + 6 * i], 6) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
}
- memcpy(addr, &rbtx4938_ethaddr[4 + 6 * ch], 6);
return 0;
}
+device_initcall(rbtx4938_ethaddr_init);
#endif /* CONFIG_PCI */
static void __init rbtx4938_spi_setup(void)
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs
2007-06-29 13:35 [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs Atsushi Nemoto
@ 2007-07-02 13:43 ` Atsushi Nemoto
2007-07-04 11:00 ` Ralf Baechle
0 siblings, 1 reply; 5+ messages in thread
From: Atsushi Nemoto @ 2007-07-02 13:43 UTC (permalink / raw)
To: linux-mips; +Cc: ralf, sshtylyov, mlachwani, jeff
On Fri, 29 Jun 2007 22:35:01 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> wrote:
> * Use platform_device to provide ethernet addresses for internal NICs.
Oops, a calculation of checksum was wrong --- revised.
Subject: [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs
* Fix pci ops for secondary PCIC
* Do not reserve 1MB for PCI MEM region (leave PCIBIOS_MIN_MEM zero)
* Use platform_device to provide ethernet addresses for internal NICs.
(background: TX49XX SoCs include PCI NIC (TC35815 compatible)
connected via its internal PCI bus, but the NIC's PROM interface is
not connected to SEEPROM. So we must provide its ethernet address
by another way.)
* Check return value of early_read_config_word()
Signed-off-by: Atsushi Nemoto <anemo@mba.ocn.ne.jp>
---
A driver side of this patch is:
"[PATCH] tc35815: Load MAC address via platform_device"
arch/mips/pci/ops-tx4938.c | 80 +++++++++++++++++-----------
arch/mips/tx4938/toshiba_rbtx4938/setup.c | 53 ++++++++-----------
2 files changed, 70 insertions(+), 63 deletions(-)
diff --git a/arch/mips/pci/ops-tx4938.c b/arch/mips/pci/ops-tx4938.c
index 4450070..a450c40 100644
--- a/arch/mips/pci/ops-tx4938.c
+++ b/arch/mips/pci/ops-tx4938.c
@@ -46,50 +46,63 @@ struct resource tx4938_pcic1_pci_mem_resource = {
.flags = IORESOURCE_MEM
};
-static int mkaddr(int bus, int dev_fn, int where, int *flagsp)
+static int mkaddr(int bus, int dev_fn, int where,
+ struct tx4938_pcic_reg *pcicptr)
{
if (bus > 0) {
/* Type 1 configuration */
- tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
((dev_fn & 0xff) << 0x08) | (where & 0xfc) | 1;
} else {
if (dev_fn >= PCI_DEVFN(TX4938_PCIC_MAX_DEVNU, 0))
return -1;
/* Type 0 configuration */
- tx4938_pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
+ pcicptr->g2pcfgadrs = ((bus & 0xff) << 0x10) |
((dev_fn & 0xff) << 0x08) | (where & 0xfc);
}
/* clear M_ABORT and Disable M_ABORT Int. */
- tx4938_pcicptr->pcistatus =
- (tx4938_pcicptr->pcistatus & 0x0000ffff) |
+ pcicptr->pcistatus =
+ (pcicptr->pcistatus & 0x0000ffff) |
(PCI_STATUS_REC_MASTER_ABORT << 16);
- tx4938_pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
+ pcicptr->pcimask &= ~PCI_STATUS_REC_MASTER_ABORT;
return 0;
}
-static int check_abort(int flags)
+static int check_abort(struct tx4938_pcic_reg *pcicptr)
{
int code = PCIBIOS_SUCCESSFUL;
/* wait write cycle completion before checking error status */
- while (tx4938_pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
+ while (pcicptr->pcicstatus & TX4938_PCIC_PCICSTATUS_IWB)
;
- if (tx4938_pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
- tx4938_pcicptr->pcistatus =
- (tx4938_pcicptr->
+ if (pcicptr->pcistatus & (PCI_STATUS_REC_MASTER_ABORT << 16)) {
+ pcicptr->pcistatus =
+ (pcicptr->
pcistatus & 0x0000ffff) | (PCI_STATUS_REC_MASTER_ABORT
<< 16);
- tx4938_pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
+ pcicptr->pcimask |= PCI_STATUS_REC_MASTER_ABORT;
code = PCIBIOS_DEVICE_NOT_FOUND;
}
return code;
}
+extern struct pci_controller tx4938_pci_controller[];
+extern struct tx4938_pcic_reg *get_tx4938_pcicptr(int ch);
+
+static struct tx4938_pcic_reg *pci_bus_to_pcicptr(struct pci_bus *bus)
+{
+ struct pci_controller *channel = bus->sysdata;
+ return get_tx4938_pcicptr(channel - &tx4938_pci_controller[0]);
+}
+
static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
int where, int size, u32 * val)
{
- int flags, retval, dev, busno, func;
+ int retval, dev, busno, func;
+ struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
+ void __iomem *cfgdata =
+ (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
dev = PCI_SLOT(devfn);
func = PCI_FUNC(devfn);
@@ -101,32 +114,32 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
busno = 0;
}
- if (mkaddr(busno, devfn, where, &flags))
+ if (mkaddr(busno, devfn, where, pcicptr))
return -1;
switch (size) {
case 1:
- *val = *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
- ((where & 3) ^ 3));
+ cfgdata += (where & 3) ^ 3;
#else
- (where & 3));
+ cfgdata += where & 3;
#endif
+ *val = __raw_readb(cfgdata);
break;
case 2:
- *val = *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
- ((where & 3) ^ 2));
+ cfgdata += (where & 2) ^ 2;
#else
- (where & 3));
+ cfgdata += where & 2;
#endif
+ *val = __raw_readw(cfgdata);
break;
case 4:
- *val = tx4938_pcicptr->g2pcfgdata;
+ *val = __raw_readl(cfgdata);
break;
}
- retval = check_abort(flags);
+ retval = check_abort(pcicptr);
if (retval == PCIBIOS_DEVICE_NOT_FOUND)
*val = 0xffffffff;
@@ -136,7 +149,10 @@ static int tx4938_pcibios_read_config(struct pci_bus *bus, unsigned int devfn,
static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn, int where,
int size, u32 val)
{
- int flags, dev, busno, func;
+ int dev, busno, func;
+ struct tx4938_pcic_reg *pcicptr = pci_bus_to_pcicptr(bus);
+ void __iomem *cfgdata =
+ (void __iomem *)(unsigned long)&pcicptr->g2pcfgdata;
busno = bus->number;
dev = PCI_SLOT(devfn);
@@ -149,32 +165,32 @@ static int tx4938_pcibios_write_config(struct pci_bus *bus, unsigned int devfn,
busno = 0;
}
- if (mkaddr(busno, devfn, where, &flags))
+ if (mkaddr(busno, devfn, where, pcicptr))
return -1;
switch (size) {
case 1:
- *(volatile u8 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
- ((where & 3) ^ 3)) = val;
+ cfgdata += (where & 3) ^ 3;
#else
- (where & 3)) = val;
+ cfgdata += where & 3;
#endif
+ __raw_writeb(val, cfgdata);
break;
case 2:
- *(volatile u16 *) ((unsigned long) & tx4938_pcicptr->g2pcfgdata |
#ifdef __BIG_ENDIAN
- ((where & 0x3) ^ 0x2)) = val;
+ cfgdata += (where & 2) ^ 2;
#else
- (where & 3)) = val;
+ cfgdata += where & 2;
#endif
+ __raw_writew(val, cfgdata);
break;
case 4:
- tx4938_pcicptr->g2pcfgdata = val;
+ __raw_writel(val, cfgdata);
break;
}
- return check_abort(flags);
+ return check_abort(pcicptr);
}
struct pci_ops tx4938_pci_ops = {
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
index 361d89a..6ed39a5 100644
--- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c
+++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c
@@ -352,7 +352,7 @@ static struct pci_dev *fake_pci_dev(struct pci_controller *hose,
static struct pci_dev dev;
static struct pci_bus bus;
- dev.sysdata = (void *)hose;
+ dev.sysdata = bus.sysdata = hose;
dev.devfn = devfn;
bus.number = busnr;
bus.ops = hose->pci_ops;
@@ -385,8 +385,10 @@ int txboard_pci66_check(struct pci_controller *hose, int top_bus, int current_bu
printk("PCI: Checking 66MHz capabilities...\n");
for (pci_devfn=devfn_start; pci_devfn<devfn_stop; pci_devfn++) {
- early_read_config_word(hose, top_bus, current_bus, pci_devfn,
- PCI_VENDOR_ID, &vid);
+ if (early_read_config_word(hose, top_bus, current_bus,
+ pci_devfn, PCI_VENDOR_ID,
+ &vid) != PCIBIOS_SUCCESSFUL)
+ continue;
if (vid == 0xffff) continue;
@@ -463,7 +465,6 @@ static int __init tx4938_pcibios_init(void)
int extarb = !(tx4938_ccfgptr->ccfg & TX4938_CCFG_PCIXARB);
PCIBIOS_MIN_IO = 0x00001000UL;
- PCIBIOS_MIN_MEM = 0x01000000UL;
mem_base[0] = txboard_request_phys_region_shrink(&mem_size[0]);
io_base[0] = txboard_request_phys_region_shrink(&io_size[0]);
@@ -578,18 +579,17 @@ arch_initcall(tx4938_pcibios_init);
#define SRTC_CS 2 /* IOC */
#ifdef CONFIG_PCI
-static unsigned char rbtx4938_ethaddr[17];
static int __init rbtx4938_ethaddr_init(void)
{
+ unsigned char dat[17];
unsigned char sum;
int i;
/* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */
- if (spi_eeprom_read(SEEPROM1_CS, 0,
- rbtx4938_ethaddr, sizeof(rbtx4938_ethaddr)))
+ if (spi_eeprom_read(SEEPROM1_CS, 0, dat, sizeof(dat))) {
printk(KERN_ERR "seeprom: read error.\n");
- else {
- unsigned char *dat = rbtx4938_ethaddr;
+ return -ENODEV;
+ } else {
if (strcmp(dat, "MAC") != 0)
printk(KERN_WARNING "seeprom: bad signature.\n");
for (i = 0, sum = 0; i < sizeof(dat); i++)
@@ -597,31 +597,22 @@ static int __init rbtx4938_ethaddr_init(void)
if (sum)
printk(KERN_WARNING "seeprom: bad checksum.\n");
}
- return 0;
-}
-device_initcall(rbtx4938_ethaddr_init);
-
-int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr)
-{
- struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata;
- int ch = 0;
-
- if (channel != &tx4938_pci_controller[1])
- return -ENODEV;
- /* TX4938 PCIC1 */
- switch (PCI_SLOT(dev->devfn)) {
- case TX4938_PCIC_IDSEL_AD_TO_SLOT(31):
- ch = 0;
- break;
- case TX4938_PCIC_IDSEL_AD_TO_SLOT(30):
- ch = 1;
- break;
- default:
- return -ENODEV;
+ for (i = 0; i < 2; i++) {
+ unsigned int slot = TX4938_PCIC_IDSEL_AD_TO_SLOT(31 - i);
+ unsigned int id = (1 << 8) | PCI_DEVFN(slot, 0); /* bus 1 */
+ struct platform_device *pdev;
+ if (!(tx4938_ccfgptr->pcfg &
+ (i ? TX4938_PCFG_ETH1_SEL : TX4938_PCFG_ETH0_SEL)))
+ continue;
+ pdev = platform_device_alloc("tc35815-mac", id);
+ if (!pdev ||
+ platform_device_add_data(pdev, &dat[4 + 6 * i], 6) ||
+ platform_device_add(pdev))
+ platform_device_put(pdev);
}
- memcpy(addr, &rbtx4938_ethaddr[4 + 6 * ch], 6);
return 0;
}
+device_initcall(rbtx4938_ethaddr_init);
#endif /* CONFIG_PCI */
static void __init rbtx4938_spi_setup(void)
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs
2007-07-02 13:43 ` Atsushi Nemoto
@ 2007-07-04 11:00 ` Ralf Baechle
0 siblings, 0 replies; 5+ messages in thread
From: Ralf Baechle @ 2007-07-04 11:00 UTC (permalink / raw)
To: Atsushi Nemoto; +Cc: linux-mips, sshtylyov, mlachwani, jeff
On Mon, Jul 02, 2007 at 10:43:06PM +0900, Atsushi Nemoto wrote:
> On Fri, 29 Jun 2007 22:35:01 +0900 (JST), Atsushi Nemoto <anemo@mba.ocn.ne.jp> wrote:
> > * Use platform_device to provide ethernet addresses for internal NICs.
>
> Oops, a calculation of checksum was wrong --- revised.
Queued for 2.6.23.
Ralf
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-07-04 11:00 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-06-29 13:35 [PATCH] rbtx4938: Fix secondary PCIC and glue internal NICs Atsushi Nemoto
2007-07-02 13:43 ` Atsushi Nemoto
2007-07-04 11:00 ` Ralf Baechle
-- strict thread matches above, loose matches on Subject: below --
2007-03-16 16:25 Atsushi Nemoto
2007-05-09 15:03 ` Atsushi Nemoto
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox