#include "../include/main.h"
#include "../include/mpc5200.h"
#include "../include/mscan.h"
+#include "linux/of.h"
+#include "linux/of_platform.h"
+
+int mpc5200_init_device_node(struct canchip_t * chip, struct device_node * devnode);
+
+/* in time when release_io should take place, we dont know the
+ * base addresses that has to be free.
+ * This variable keeps those addresses
+ */
+unsigned long * chips_addr;
+
int mpc5200_request_io(struct candevice_t *candev)
{
- if (!can_request_io_region(candev->io_addr, candev->nr_all_chips * IO_RANGE, DEVICE_NAME)) {
- CANMSG("Unable to open port: 0x%lx\n",candev->io_addr);
- return -ENODEV;
+ int chipnr;
+ struct device_node * dn;
+ const char * of_devname = "can";
+
+ /* Workaround for OpenFormware */
+
+ /* Select device by chipnr:
+ * first dev is @ 900
+ * second dev is @ 980
+ *
+ * There are only two devices on MPC5200 */
+
+ /* initialize internal address storage */
+ chips_addr = (unsigned long*)kmalloc(candev->nr_all_chips * sizeof(unsigned long), GFP_KERNEL);
+
+ /* DEBUGMSG("Looking for device node '%s'\n", of_devname); */
+
+ chipnr = 0;
+ for_each_node_by_name(dn, of_devname)
+ {
+ /* DEBUGMSG(" got OF node (%s)...\n", of_devname); */
+
+ if (!of_device_is_available(dn))
+ {
+ DEBUGMSG("\tdevice not available\n");
+ continue;
+ }
+
+
+ if (mpc5200_init_device_node(candev->chip[chipnr], dn))
+ return -ENODEV;
+
+ /* fill received address to internal storage */
+ chips_addr[chipnr] = (unsigned long)candev->chip[chipnr]->chip_base_addr;
+
+ /* original MIDAM Shark board use only one CAN chip - this handles similar cases */
+ if (++chipnr >= candev->nr_all_chips)
+ break;
}
- DEBUGMSG("Registered IO-memory: 0x%lx - 0x%lx\n", candev->io_addr, candev->io_addr + candev->nr_all_chips * IO_RANGE - 1);
+
+ DEBUGMSG("Succesfully mapped %d can devices\n", chipnr);
return 0;
}
int mpc5200_release_io(struct candevice_t *candev)
{
- can_release_io_region(candev->io_addr, candev->nr_all_chips * IO_RANGE);
+ int i;
+ /*can_release_io_region(candev->io_addr, candev->nr_all_chips * IO_RANGE);*/
+
+ /* free all chips memorey space - using internal address storage */
+ for (i = 0; i < candev->nr_all_chips; i++)
+ iounmap((void*)chips_addr[i]);
+
return 0;
}
for (i = 0; i < candev->nr_all_chips; i++)
{
/* !!! Assuming this card has ONLY MSCAN chips !!! */
- if (mscan_reset_chip(candev->chip[i])) return -ENODEV;
+ if (mscan_reset_chip(candev->chip[i]))
+ return -ENODEV;
}
return 0;
{
mscan_fill_chipspecops(candev->chip[chipnr]);
- candev->chip[chipnr]->chip_base_addr = can_ioport2ioptr(candev->io_addr) + chipnr * MPC5200_CAN_CHIP_OFFSET; /* one chip with 2 interfaces */
candev->chip[chipnr]->clock = MPC5200_CLK_FREQ;
- candev->chip[chipnr]->chip_irq = MPC5200_CAN_IRQ + chipnr;
candev->chip[chipnr]->hostdevice = candev;
+/*
+ candev->chip[chipnr]->chip_base_addr = can_ioport2ioptr(candev->io_addr) + chipnr * MPC5200_CAN_CHIP_OFFSET; one chip with 2 interfaces
+ candev->chip[chipnr]->chip_irq = MPC5200_CAN_IRQ + chipnr;
+*/
+ DEBUGMSG("mpc5200_init_chip_data\n");
+
return 0;
}
void mpc5200_write_register(unsigned data, can_ioptr_t address)
{
/* address is an absolute address */
- DEBUGMSG("write register\n");
+ /* DEBUGMSG("write register\n"); */
writeb(data, address); /* regs in PowerPC (5200) are one-byte length */
}
unsigned mpc5200_read_register(can_ioptr_t address)
{
/* address is an absolute address */
- DEBUGMSG("read register\n");
+ /* DEBUGMSG("read register\n"); */
return readb(address); /* regs in PowerPC (5200) are one-byte length */
}
hwspecops->init_hw_data = mpc5200_init_hw_data;
hwspecops->init_chip_data = mpc5200_init_chip_data;
hwspecops->init_obj_data = mpc5200_init_obj_data;
- hwspecops->program_irq = mpc5200_program_irq;
+ hwspecops->program_irq = NULL; /* mpc5200_program_irq; */
hwspecops->write_register = mpc5200_write_register;
hwspecops->read_register = mpc5200_read_register;
return 0;
}
+
+
+int mpc5200_init_device_node(struct canchip_t * chip, struct device_node * devnode)
+{
+ chip->chip_base_addr = of_iomap(devnode, 0);
+ if (!chip->chip_base_addr)
+ {
+ DEBUGMSG("\tcannot map IO - of_iomap\n");
+ return -ENODEV;
+ }
+
+ chip->chip_irq = irq_of_parse_and_map(devnode, 0);
+ if (!chip->chip_irq)
+ {
+ DEBUGMSG("\tcannot map IRQ\n");
+ iounmap(chip->chip_base_addr);
+ return -ENODEV;
+ }
+
+ DEBUGMSG("Bound to io-addr: 0x%08x IRQ: %d\n", (unsigned int)chip->chip_base_addr, chip->chip_irq);
+
+ return 0;
+}