Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 26315
b: refs/heads/master
c: e27987c
h: refs/heads/master
i:
  26313: 9505ede
  26311: eff9d66
v: v3
  • Loading branch information
Vitaly Bordug authored and Paul Mackerras committed Apr 28, 2006
1 parent 7ec4633 commit a40122f
Show file tree
Hide file tree
Showing 5 changed files with 221 additions and 112 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a73c87bfe98f4d54c919e920a6efb0a116115722
refs/heads/master: e27987cddd8db3a72a0f4734b5d94d06c7677323
16 changes: 9 additions & 7 deletions trunk/drivers/serial/cpm_uart/cpm_uart.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
#define CPM_UART_H

#include <linux/config.h>
#include <linux/platform_device.h>
#include <linux/fs_uart_pd.h>

#if defined(CONFIG_CPM2)
#include "cpm_uart_cpm2.h"
Expand All @@ -26,14 +28,14 @@
#define FLAG_SMC 0x00000002
#define FLAG_CONSOLE 0x00000001

#define UART_SMC1 0
#define UART_SMC2 1
#define UART_SCC1 2
#define UART_SCC2 3
#define UART_SCC3 4
#define UART_SCC4 5
#define UART_SMC1 fsid_smc1_uart
#define UART_SMC2 fsid_smc2_uart
#define UART_SCC1 fsid_scc1_uart
#define UART_SCC2 fsid_scc2_uart
#define UART_SCC3 fsid_scc3_uart
#define UART_SCC4 fsid_scc4_uart

#define UART_NR 6
#define UART_NR fs_uart_nr

#define RX_NUM_FIFO 4
#define RX_BUF_SIZE 32
Expand Down
259 changes: 211 additions & 48 deletions trunk/drivers/serial/cpm_uart/cpm_uart_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
#include <linux/device.h>
#include <linux/bootmem.h>
#include <linux/dma-mapping.h>
#include <linux/fs_uart_pd.h>

#include <asm/io.h>
#include <asm/irq.h>
Expand All @@ -60,7 +61,7 @@
/* Track which ports are configured as uarts */
int cpm_uart_port_map[UART_NR];
/* How many ports did we config as uarts */
int cpm_uart_nr;
int cpm_uart_nr = 0;

/**************************************************************/

Expand All @@ -85,6 +86,37 @@ static inline void *cpm2cpu_addr(unsigned long addr)
return bus_to_virt(addr);
}

/* Place-holder for board-specific stuff */
struct platform_device* __attribute__ ((weak)) __init
early_uart_get_pdev(int index)
{
return NULL;
}


void cpm_uart_count(void)
{
cpm_uart_nr = 0;
#ifdef CONFIG_SERIAL_CPM_SMC1
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC1;
#endif
#ifdef CONFIG_SERIAL_CPM_SMC2
cpm_uart_port_map[cpm_uart_nr++] = UART_SMC2;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC1
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC1;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC2
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC2;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC3
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC3;
#endif
#ifdef CONFIG_SERIAL_CPM_SCC4
cpm_uart_port_map[cpm_uart_nr++] = UART_SCC4;
#endif
}

/*
* Check, if transmit buffers are processed
*/
Expand Down Expand Up @@ -829,14 +861,6 @@ static int cpm_uart_request_port(struct uart_port *port)
if (pinfo->flags & FLAG_CONSOLE)
return 0;

/*
* Setup any port IO, connect any baud rate generators,
* etc. This is expected to be handled by board
* dependant code
*/
if (pinfo->set_lineif)
pinfo->set_lineif(pinfo);

if (IS_SMC(pinfo)) {
pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
Expand Down Expand Up @@ -988,6 +1012,54 @@ struct uart_cpm_port cpm_uart_ports[UART_NR] = {
},
};

int cpm_uart_drv_get_platform_data(struct platform_device *pdev, int is_con)
{
struct resource *r;
struct fs_uart_platform_info *pdata = pdev->dev.platform_data;
int idx = pdata->fs_no; /* It is UART_SMCx or UART_SCCx index */
struct uart_cpm_port *pinfo;
int line;
u32 mem, pram;

for (line=0; line<UART_NR && cpm_uart_port_map[line]!=pdata->fs_no; line++);

pinfo = (struct uart_cpm_port *) &cpm_uart_ports[idx];

pinfo->brg = pdata->brg;

if (!is_con) {
pinfo->port.line = line;
pinfo->port.flags = UPF_BOOT_AUTOCONF;
}

if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs")))
return -EINVAL;
mem = r->start;

if (!(r = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pram")))
return -EINVAL;
pram = r->start;

if(idx > fsid_smc2_uart) {
pinfo->sccp = (scc_t *)mem;
pinfo->sccup = (scc_uart_t *)pram;
} else {
pinfo->smcp = (smc_t *)mem;
pinfo->smcup = (smc_uart_t *)pram;
}
pinfo->tx_nrfifos = pdata->tx_num_fifo;
pinfo->tx_fifosize = pdata->tx_buf_size;

pinfo->rx_nrfifos = pdata->rx_num_fifo;
pinfo->rx_fifosize = pdata->rx_buf_size;

pinfo->port.uartclk = pdata->uart_clk;
pinfo->port.mapbase = (unsigned long)mem;
pinfo->port.irq = platform_get_irq(pdev, 0);

return 0;
}

#ifdef CONFIG_SERIAL_CPM_CONSOLE
/*
* Print a string to the serial port trying not to disturb
Expand Down Expand Up @@ -1067,9 +1139,7 @@ static void cpm_uart_console_write(struct console *co, const char *s,
pinfo->tx_cur = (volatile cbd_t *) bdp;
}

/*
* Setup console. Be careful is called early !
*/

static int __init cpm_uart_console_setup(struct console *co, char *options)
{
struct uart_port *port;
Expand All @@ -1080,9 +1150,27 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
int flow = 'n';
int ret;

struct fs_uart_platform_info *pdata;
struct platform_device* pdev = early_uart_get_pdev(co->index);

port =
(struct uart_port *)&cpm_uart_ports[cpm_uart_port_map[co->index]];
pinfo = (struct uart_cpm_port *)port;
if (!pdev) {
pr_info("cpm_uart: console: compat mode\n");
/* compatibility - will be cleaned up */
cpm_uart_init_portdesc();

if (pinfo->set_lineif)
pinfo->set_lineif(pinfo);
} else {
pdata = pdev->dev.platform_data;
if (pdata)
if (pdata->init_ioports)
pdata->init_ioports();

cpm_uart_drv_get_platform_data(pdev, 1);
}

pinfo->flags |= FLAG_CONSOLE;

Expand All @@ -1097,14 +1185,6 @@ static int __init cpm_uart_console_setup(struct console *co, char *options)
baud = 9600;
}

/*
* Setup any port IO, connect any baud rate generators,
* etc. This is expected to be handled by board
* dependant code
*/
if (pinfo->set_lineif)
pinfo->set_lineif(pinfo);

if (IS_SMC(pinfo)) {
pinfo->smcp->smc_smcm &= ~(SMCM_RX | SMCM_TX);
pinfo->smcp->smc_smcmr &= ~(SMCMR_REN | SMCMR_TEN);
Expand Down Expand Up @@ -1143,11 +1223,8 @@ static struct console cpm_scc_uart_console = {

int __init cpm_uart_console_init(void)
{
int ret = cpm_uart_init_portdesc();

if (!ret)
register_console(&cpm_scc_uart_console);
return ret;
register_console(&cpm_scc_uart_console);
return 0;
}

console_initcall(cpm_uart_console_init);
Expand All @@ -1165,44 +1242,130 @@ static struct uart_driver cpm_reg = {
.minor = SERIAL_CPM_MINOR,
.cons = CPM_UART_CONSOLE,
};

static int __init cpm_uart_init(void)
static int cpm_uart_drv_probe(struct device *dev)
{
int ret, i;

printk(KERN_INFO "Serial: CPM driver $Revision: 0.01 $\n");
struct platform_device *pdev = to_platform_device(dev);
struct fs_uart_platform_info *pdata;
int ret = -ENODEV;

#ifndef CONFIG_SERIAL_CPM_CONSOLE
ret = cpm_uart_init_portdesc();
if (ret)
if(!pdev) {
printk(KERN_ERR"CPM UART: platform data missing!\n");
return ret;
#endif
}

cpm_reg.nr = cpm_uart_nr;
ret = uart_register_driver(&cpm_reg);
pdata = pdev->dev.platform_data;
pr_debug("cpm_uart_drv_probe: Adding CPM UART %d\n",
cpm_uart_port_map[pdata->fs_no]);

if (ret)
if ((ret = cpm_uart_drv_get_platform_data(pdev, 0)))
return ret;

for (i = 0; i < cpm_uart_nr; i++) {
int con = cpm_uart_port_map[i];
cpm_uart_ports[con].port.line = i;
cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
}
if (pdata->init_ioports)
pdata->init_ioports();

return ret;
ret = uart_add_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);

return ret;
}

static void __exit cpm_uart_exit(void)
static int cpm_uart_drv_remove(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct fs_uart_platform_info *pdata = pdev->dev.platform_data;

pr_debug("cpm_uart_drv_remove: Removing CPM UART %d\n",
cpm_uart_port_map[pdata->fs_no]);

uart_remove_one_port(&cpm_reg, &cpm_uart_ports[pdata->fs_no].port);
return 0;
}

static struct device_driver cpm_smc_uart_driver = {
.name = "fsl-cpm-smc:uart",
.bus = &platform_bus_type,
.probe = cpm_uart_drv_probe,
.remove = cpm_uart_drv_remove,
};

static struct device_driver cpm_scc_uart_driver = {
.name = "fsl-cpm-scc:uart",
.bus = &platform_bus_type,
.probe = cpm_uart_drv_probe,
.remove = cpm_uart_drv_remove,
};

/*
This is supposed to match uart devices on platform bus,
*/
static int match_is_uart (struct device* dev, void* data)
{
struct platform_device* pdev = container_of(dev, struct platform_device, dev);
int ret = 0;
/* this was setfunc as uart */
if(strstr(pdev->name,":uart")) {
ret = 1;
}
return ret;
}


static int cpm_uart_init(void) {

int ret;
int i;
struct device *dev;
printk(KERN_INFO "Serial: CPM driver $Revision: 0.02 $\n");

/* lookup the bus for uart devices */
dev = bus_find_device(&platform_bus_type, NULL, 0, match_is_uart);

/* There are devices on the bus - all should be OK */
if (dev) {
cpm_uart_count();
cpm_reg.nr = cpm_uart_nr;

if (!(ret = uart_register_driver(&cpm_reg))) {
if ((ret = driver_register(&cpm_smc_uart_driver))) {
uart_unregister_driver(&cpm_reg);
return ret;
}
if ((ret = driver_register(&cpm_scc_uart_driver))) {
driver_unregister(&cpm_scc_uart_driver);
uart_unregister_driver(&cpm_reg);
}
}
} else {
/* No capable platform devices found - falling back to legacy mode */
pr_info("cpm_uart: WARNING: no UART devices found on platform bus!\n");
pr_info(
"cpm_uart: the driver will guess configuration, but this mode is no longer supported.\n");
#ifndef CONFIG_SERIAL_CPM_CONSOLE
ret = cpm_uart_init_portdesc();
if (ret)
return ret;
#endif

cpm_reg.nr = cpm_uart_nr;
ret = uart_register_driver(&cpm_reg);

if (ret)
return ret;

for (i = 0; i < cpm_uart_nr; i++) {
int con = cpm_uart_port_map[i];
cpm_uart_ports[con].port.line = i;
cpm_uart_ports[con].port.flags = UPF_BOOT_AUTOCONF;
uart_add_one_port(&cpm_reg, &cpm_uart_ports[con].port);
}

for (i = 0; i < cpm_uart_nr; i++) {
int con = cpm_uart_port_map[i];
uart_remove_one_port(&cpm_reg, &cpm_uart_ports[con].port);
}
return ret;
}

static void __exit cpm_uart_exit(void)
{
driver_unregister(&cpm_scc_uart_driver);
driver_unregister(&cpm_smc_uart_driver);
uart_unregister_driver(&cpm_reg);
}

Expand Down
Loading

0 comments on commit a40122f

Please sign in to comment.