[PATCH 6/6] [RFC] POWERPC: Add mpc8560 board support
Kumar Gala
galak at kernel.crashing.org
Mon Jun 26 23:35:37 EST 2006
[snip]
>>> diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/
>>> Makefile
>>> index cef95b0..75dfe12 100644
>>> --- a/arch/powerpc/sysdev/Makefile
>>> +++ b/arch/powerpc/sysdev/Makefile
>>> @@ -12,3 +12,10 @@ obj-$(CONFIG_U3_DART) +=
>>> dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
>>> obj-$(CONFIG_PPC_83xx) += ipic.o
>>> obj-$(CONFIG_FSL_SOC) += fsl_soc.o
>>> +
>>> +# Temporary hack until we have migrated to asm-powerpc
>>> +ifeq ($(ARCH),powerpc)
>>> +obj-$(CONFIG_CPM2) += cpm2_common.o cpm2_pic.o
>>> +endif
>>
>> See earlier comments about just building in arch/powerpc
>>
> Hrm, here I am not completely sure it's a good thing. The point is
> that
> currently some OF-specific stuff is under construction to go into
> cpm2_common at least (for instance, getting rid of CPM_MAP_ADDR
> ioremap because the offset is available via oftree, and things like
> that).
If that's the case, make a duplicate of cpm2_common.c, however I dont
think you need the ifeq... to make that work.
>>> +
>>> +#obj-$(CONFIG_CPM2) += cpm2/
what's in the cpm2 directory?
[snip]
>>> diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/
>>> fsl_soc.c
>>> index ceb5846..bab202d 100644
>>> --- a/arch/powerpc/sysdev/fsl_soc.c
>>> +++ b/arch/powerpc/sysdev/fsl_soc.c
>>> @@ -21,6 +21,8 @@ #include <linux/module.h>
>>> #include <linux/device.h>
>>> #include <linux/platform_device.h>
>>> #include <linux/fsl_devices.h>
>>> +#include <linux/fs_enet_pd.h>
>>> +#include <linux/fs_uart_pd.h>
>>>
>>> #include <asm/system.h>
>>> #include <asm/atomic.h>
>>> @@ -30,6 +32,10 @@ #include <asm/prom.h>
>>> #include <sysdev/fsl_soc.h>
>>> #include <mm/mmu_decl.h>
>>>
>>> +#ifdef CONFIG_CPM2
>>> +#include <asm/cpm2.h>
>>> +#endif
>>> +
>>> static phys_addr_t immrbase = -1;
>>>
>>> phys_addr_t get_immrbase(void)
>>> @@ -43,7 +49,9 @@ phys_addr_t get_immrbase(void)
>>> if (soc) {
>>> unsigned int size;
>>> void *prop = get_property(soc, "reg", &size);
>>> - immrbase = of_translate_address(soc, prop);
>>> +
>>> + if (prop)
>>> + immrbase = of_translate_address(soc, prop);
>>> of_node_put(soc);
>>> };
>>>
>>> @@ -51,7 +59,79 @@ phys_addr_t get_immrbase(void)
>>> }
>>>
>>> EXPORT_SYMBOL(get_immrbase);
>>> +
>>> +static u32 brgfreq = -1;
>>> +
>>> +u32 get_brgfreq(void)
>>> +{
>>> + struct device_node *node;
>>> +
>>> + if (brgfreq != -1)
>>> + return brgfreq;
>>> +
>>> + node = of_find_node_by_type(NULL, "serial");
>>> + if (node) {
>>> + unsigned int size;
>>> + unsigned int *prop = (unsigned
>>> int*)get_property(node, "clock- frequency", &size);
>>> +
>>> + if (prop)
>>> + brgfreq = *prop;
>>> + of_node_put(node);
>>> + };
>>> +
>>> + return brgfreq;
>>> +}
>>
>> These seems broken on a system w/both CPM & 8250 style uarts.
>>
> Yeah, missed that.
>
>>> +
>>> +EXPORT_SYMBOL(get_brgfreq);
>>> +
>>> +static u32 fs_baudrate = -1;
>>> +
>>> +u32 get_baudrate(void)
>>> +{
>>> + struct device_node *node;
>>>
>>> + if (fs_baudrate != -1)
>>> + return fs_baudrate;
>>> +
>>> + node = of_find_node_by_type(NULL, "serial");
>>> + if (node) {
>>> + unsigned int size;
>>> + unsigned int *prop = (unsigned
>>> int*)get_property(node, "current- speed", &size);
>>> +
>>> + if (prop)
>>> + fs_baudrate = *prop;
>>> + of_node_put(node);
>>> + };
>>> +
>>> + return fs_baudrate;
>>> +}
>>> +
>>> +EXPORT_SYMBOL(get_baudrate);
>>> +
>>> +static u32 intfreq = -1;
>>> +
>>> +u32 get_intfreq(void)
>>> +{
>>> + struct device_node *node;
>>> +
>>> + if (intfreq != -1)
>>> + return intfreq;
>>> +
>>> + node = of_find_node_by_type(NULL, "cpu");
>>> + if (node) {
>>> + unsigned int size;
>>> + unsigned int *prop = (unsigned
>>> int*)get_property(node, "clock- frequency", &size);
>>> + if (prop)
>>> + intfreq = *prop;
>>> + of_node_put(node);
>>> + }
>>> +
>>> + return intfreq;
>>> +}
>>> +
>>> +EXPORT_SYMBOL(get_intfreq);
>>> +
>>
>> Don't we have something that reports "clock-frequency" elsewhere?
>>
>
> If yes, I haven't found... Mind pointing where to look at?
ppc_proc_freq in kernel/time.c
>>> +
>>> static int __init gfar_mdio_of_init(void)
>>> {
>>> struct device_node *np;
>>> @@ -491,3 +571,211 @@ err:
>>> }
>>>
>>> arch_initcall(fsl_usb_dr_of_init);
>>> +
>>> +static const char *fcc_regs = "fcc_regs";
>>> +static const char *fcc_regs_c = "fcc_regs_c";
>>> +static const char *fcc_pram = "fcc_pram";
>>> +static char bus_id[9][BUS_ID_SIZE];
>>> +
>>> +static int __init fs_enet_of_init(void)
>>> +{
>>> + struct device_node *np;
>>> + unsigned int i;
>>> + struct platform_device *fs_enet_dev;
>>> + struct resource res;
>>> + int ret;
>>> +
>>> + for (np = NULL, i = 0;
>>> + (np = of_find_compatible_node(np, "network",
>>> "fs_enet")) != NULL;
>>> + i++) {
>>> + struct resource r[4];
>>> + struct device_node *phy, *mdio;
>>> + struct fs_platform_info fs_enet_data;
>>> + unsigned int *id, *phy_addr;
>>> + void *mac_addr;
>>> + phandle *ph;
>>> + char *model;
>>> +
>>> + memset(r, 0, sizeof(r));
>>> + memset(&fs_enet_data, 0, sizeof(fs_enet_data));
>>> +
>>> + ret = of_address_to_resource(np, 0, &r[0]);
>>> + if (ret)
>>> + goto err;
>>> + r[0].name = fcc_regs;
>>> +
>>> + ret = of_address_to_resource(np, 1, &r[1]);
>>> + if (ret)
>>> + goto err;
>>> + r[1].name = fcc_pram;
>>> +
>>> + ret = of_address_to_resource(np, 2, &r[2]);
>>> + if (ret)
>>> + goto err;
>>> + r[2].name = fcc_regs_c;
>>> +
>>> + r[3].start = np->intrs[0].line;
>>> + r[3].end = np->intrs[0].line;
>>> + r[3].flags = IORESOURCE_IRQ;
>>> +
>>> + fs_enet_dev =
>>> + platform_device_register_simple("fsl-cpm-fcc",
>>> i, &r[0], 4); +
>>> + if (IS_ERR(fs_enet_dev)) {
>>> + ret = PTR_ERR(fs_enet_dev);
>>> + goto err;
>>> + }
>>> +
>>> + model = get_property(np, "model", NULL);
>>> + if (model == NULL) {
>>> + ret = -ENODEV;
>>> + goto unreg;
>>> + }
>>> +
>>> + mac_addr = get_property(np, "mac-address", NULL);
>>> + memcpy(fs_enet_data.macaddr, mac_addr, 6);
>>> +
>>> + ph = (phandle *) get_property(np, "phy-handle",
>>> NULL);
>>> + phy = of_find_node_by_phandle(*ph);
>>> +
>>> + if (phy == NULL) {
>>> + ret = -ENODEV;
>>> + goto unreg;
>>> + }
>>> +
>>> + phy_addr = (u32 *) get_property(phy, "reg", NULL);
>>> + fs_enet_data.phy_addr = *phy_addr;
>>> +
>>> + id = (u32 *) get_property(np, "device-id", NULL);
>>> + fs_enet_data.fs_no = *id;
>>> +
>>> + mdio = of_get_parent(phy);
>>> + ret = of_address_to_resource(mdio, 0, &res);
>>> + if (ret) {
>>> + of_node_put(phy);
>>> + of_node_put(mdio);
>>> + goto unreg;
>>> + }
>>> +
>>> + switch (*id) {
>>> + case fsid_fcc1:
>>> + fs_enet_data.mem_offset = FCC1_MEM_OFFSET,
>>> + snprintf((char*)&bus_id[2], BUS_ID_SIZE,
>>> "%x:%02x", (u32) res.start, fs_enet_data.phy_addr);
>>> + fs_enet_data.bus_id = (char*)&bus_id[2];
>>> + fs_enet_data.cp_page = CPM_CR_FCC1_PAGE;
>>> + fs_enet_data.cp_block = CPM_CR_FCC1_SBLOCK;
>>> + break;
>>> + case fsid_fcc2:
>>> + fs_enet_data.mem_offset = FCC2_MEM_OFFSET,
>>> + snprintf((char*)&bus_id[3], BUS_ID_SIZE,
>>> "%x:%02x", (u32) res.start, fs_enet_data.phy_addr);
>>> + fs_enet_data.bus_id = (char*)&bus_id[3];
>>> + fs_enet_data.cp_page = CPM_CR_FCC2_PAGE;
>>> + fs_enet_data.cp_block = CPM_CR_FCC2_SBLOCK;
>>> + break;
>>> + case fsid_fcc3:
>>> + fs_enet_data.mem_offset = FCC3_MEM_OFFSET,
>>> + snprintf((char*)&bus_id[4], BUS_ID_SIZE,
>>> "%x:%02x", (u32) res.start, fs_enet_data.phy_addr);
>>> + fs_enet_data.bus_id = (char*)&bus_id[4];
>>> + fs_enet_data.cp_page = CPM_CR_FCC3_PAGE;
>>> + fs_enet_data.cp_block = CPM_CR_FCC3_SBLOCK;
>>> + break;
>>> + }
>>
>> this looks like a lot of effort to just encode a single integer (1,
>> 2, 3) and then lookup the other information based on it.
>>
>
> Not sure I am following what is suggested here. Could it be elaborated
> a little bit ?
I saying all you need to store is the fact that its a FCC and its
number 1, 2, 3... after which we can have some table in cpm2_common.c
that provides back cp_page, cp_block based on type and number.
Encoding it fs_enet_data is just a duplication.
>>> +
>>> + if (strstr(model, "FCC")) {
>>> + fs_enet_data.dpram_offset =
>>> (u32)cpm2_immr->im_dprambase;
>>> + fs_enet_data.rx_ring = 32;
>>> + fs_enet_data.tx_ring = 32;
>>> + fs_enet_data.rx_copybreak = 240;
>>> + fs_enet_data.use_napi = 0;
>>> + fs_enet_data.napi_weight = 17;
>>> + }
>>> +
>>> + of_node_put(phy);
>>> + of_node_put(mdio);
>>> +
>>> + ret = platform_device_add_data(fs_enet_dev,
>>> &fs_enet_data,
>>> + sizeof(struct
>>> +
>>> fs_platform_info));
>>> + if (ret)
>>> + goto unreg;
>>> + }
>>> + return 0;
>>> +
>>> +unreg:
>>> + platform_device_unregister(fs_enet_dev);
>>> +err:
>>> + return ret;
>>> +}
>>> +
>>> +arch_initcall(fs_enet_of_init);
>>> +
>>> +static const char *scc_regs = "regs";
>>> +static const char *scc_pram = "pram";
>>> +
>>> +static int __init cpm_uart_of_init(void)
>>> +{
>>> + struct device_node *np;
>>> + unsigned int i;
>>> + struct platform_device *cpm_uart_dev;
>>> + int ret;
>>> +
>>> +
>>> + for (np = NULL, i = 0;
>>> + (np = of_find_compatible_node(np, "serial",
>>> "cpm_uart")) != NULL;
>>> + i++) {
>>> + struct resource r[3];
>>> + struct fs_uart_platform_info cpm_uart_data;
>>> + int *id;
>>> +
>>> + memset(r, 0, sizeof(r));
>>> + memset(&cpm_uart_data, 0, sizeof(cpm_uart_data));
>>> +
>>> + ret = of_address_to_resource(np, 0, &r[0]);
>>> + if (ret)
>>> + goto err;
>>> +
>>> + r[0].name = scc_regs;
>>> +
>>> + ret = of_address_to_resource(np, 1, &r[1]);
>>> + if (ret)
>>> + goto err;
>>> + r[1].name = scc_pram;
>>> +
>>> + r[2].start = np->intrs[0].line;
>>> + r[2].end = np->intrs[0].line;
>>> + r[2].flags = IORESOURCE_IRQ;
>>> +
>>> + cpm_uart_dev =
>>> +
>>> platform_device_register_simple("fsl-cpm-scc:uart", i, &r [0], 3);
>>> +
>>> + if (IS_ERR(cpm_uart_dev)) {
>>> + ret = PTR_ERR(cpm_uart_dev);
>>> + goto err;
>>> + }
>>> +
>>> + id = get_property(np, "device-id", NULL);
>>> + cpm_uart_data.fs_no = *id;
>>> + cpm_uart_data.uart_clk = get_intfreq();
>>> +
>>> + cpm_uart_data.tx_num_fifo = 4;
>>> + cpm_uart_data.tx_buf_size = 32;
>>> + cpm_uart_data.rx_num_fifo = 4;
>>> + cpm_uart_data.rx_buf_size = 32;
>>> +
>>> + ret =
>>> + platform_device_add_data(cpm_uart_dev,
>>> &cpm_uart_data,
>>> + sizeof(struct
>>> +
>>> fs_uart_platform_info));
>>> + if (ret)
>>> + goto unreg;
>>> + }
>>> +
>>> + return 0;
>>> +
>>> +unreg:
>>> + platform_device_unregister(cpm_uart_dev);
>>> +err:
>>> + return ret;
>>> +}
>>> +
>>> +arch_initcall(cpm_uart_of_init);
>>> diff --git a/include/asm-ppc/cpm2.h b/include/asm-ppc/cpm2.h
>>> index f6a7ff0..8e6840b 100644
>>> --- a/include/asm-ppc/cpm2.h
>>> +++ b/include/asm-ppc/cpm2.h
>>> @@ -1186,7 +1186,7 @@ #define PC3_DIRC1 (PC3_TXDAT)
>>> #define FCC_MEM_OFFSET(x) (CPM_FCC_SPECIAL_BASE + (x*128))
>>> #define FCC1_MEM_OFFSET FCC_MEM_OFFSET(0)
>>> #define FCC2_MEM_OFFSET FCC_MEM_OFFSET(1)
>>> -#define FCC2_MEM_OFFSET FCC_MEM_OFFSET(2)
>>> +#define FCC3_MEM_OFFSET FCC_MEM_OFFSET(2)
>>>
>>> #endif /* __CPM2__ */
>>> #endif /* __KERNEL__ */
>>> _______________________________________________
>>> Linuxppc-dev mailing list
>>> Linuxppc-dev at ozlabs.org
>>> https://ozlabs.org/mailman/listinfo/linuxppc-dev
>>
>>
More information about the Linuxppc-dev
mailing list