diff options
author | Magnus Damm <damm@igel.co.jp> | 2009-01-21 10:13:50 -0500 |
---|---|---|
committer | Paul Mundt <lethal@linux-sh.org> | 2009-05-08 10:08:53 -0400 |
commit | 0ee70712922c15252183db8b50a7e369c96017c0 (patch) | |
tree | c9e8fd1be30692c3c5d9d68dd041639e4e27e897 /drivers/serial | |
parent | a5660adae85918f2ab6b10ab58e2f574c1bd5ce1 (diff) |
sh-sci: allow single port platform devices
Allow registration of single port sh-sci platform devices.
Signed-off-by: Magnus Damm <damm@igel.co.jp>
Signed-off-by: Paul Mundt <lethal@linux-sh.org>
Diffstat (limited to 'drivers/serial')
-rw-r--r-- | drivers/serial/sh-sci.c | 125 |
1 files changed, 72 insertions, 53 deletions
diff --git a/drivers/serial/sh-sci.c b/drivers/serial/sh-sci.c index 17fa7f17bbe3..e9b350c58ba8 100644 --- a/drivers/serial/sh-sci.c +++ b/drivers/serial/sh-sci.c | |||
@@ -1221,6 +1221,70 @@ static int __devexit sci_remove(struct platform_device *dev) | |||
1221 | return 0; | 1221 | return 0; |
1222 | } | 1222 | } |
1223 | 1223 | ||
1224 | static int __devinit sci_probe_single(struct platform_device *dev, | ||
1225 | unsigned int index, | ||
1226 | struct plat_sci_port *p, | ||
1227 | struct sci_port *sciport) | ||
1228 | { | ||
1229 | struct sh_sci_priv *priv = platform_get_drvdata(dev); | ||
1230 | unsigned long flags; | ||
1231 | int ret; | ||
1232 | |||
1233 | /* Sanity check */ | ||
1234 | if (unlikely(index >= SCI_NPORTS)) { | ||
1235 | dev_notice(&dev->dev, "Attempting to register port " | ||
1236 | "%d when only %d are available.\n", | ||
1237 | index+1, SCI_NPORTS); | ||
1238 | dev_notice(&dev->dev, "Consider bumping " | ||
1239 | "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n"); | ||
1240 | return 0; | ||
1241 | } | ||
1242 | |||
1243 | sciport->port.mapbase = p->mapbase; | ||
1244 | |||
1245 | if (p->mapbase && !p->membase) { | ||
1246 | if (p->flags & UPF_IOREMAP) { | ||
1247 | p->membase = ioremap_nocache(p->mapbase, 0x40); | ||
1248 | if (IS_ERR(p->membase)) | ||
1249 | return PTR_ERR(p->membase); | ||
1250 | } else { | ||
1251 | /* | ||
1252 | * For the simple (and majority of) cases | ||
1253 | * where we don't need to do any remapping, | ||
1254 | * just cast the cookie directly. | ||
1255 | */ | ||
1256 | p->membase = (void __iomem *)p->mapbase; | ||
1257 | } | ||
1258 | } | ||
1259 | |||
1260 | sciport->port.membase = p->membase; | ||
1261 | |||
1262 | sciport->port.irq = p->irqs[SCIx_TXI_IRQ]; | ||
1263 | sciport->port.flags = p->flags; | ||
1264 | sciport->port.dev = &dev->dev; | ||
1265 | |||
1266 | sciport->type = sciport->port.type = p->type; | ||
1267 | |||
1268 | memcpy(&sciport->irqs, &p->irqs, sizeof(p->irqs)); | ||
1269 | |||
1270 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); | ||
1271 | |||
1272 | if (ret) { | ||
1273 | if (p->flags & UPF_IOREMAP) | ||
1274 | iounmap(p->membase); | ||
1275 | |||
1276 | return ret; | ||
1277 | } | ||
1278 | |||
1279 | INIT_LIST_HEAD(&sciport->node); | ||
1280 | |||
1281 | spin_lock_irqsave(&priv->lock, flags); | ||
1282 | list_add(&sciport->node, &priv->ports); | ||
1283 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1284 | |||
1285 | return 0; | ||
1286 | } | ||
1287 | |||
1224 | /* | 1288 | /* |
1225 | * Register a set of serial devices attached to a platform device. The | 1289 | * Register a set of serial devices attached to a platform device. The |
1226 | * list is terminated with a zero flags entry, which means we expect | 1290 | * list is terminated with a zero flags entry, which means we expect |
@@ -1232,7 +1296,6 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1232 | struct plat_sci_port *p = dev->dev.platform_data; | 1296 | struct plat_sci_port *p = dev->dev.platform_data; |
1233 | struct sh_sci_priv *priv; | 1297 | struct sh_sci_priv *priv; |
1234 | int i, ret = -EINVAL; | 1298 | int i, ret = -EINVAL; |
1235 | unsigned long flags; | ||
1236 | 1299 | ||
1237 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); | 1300 | priv = kzalloc(sizeof(*priv), GFP_KERNEL); |
1238 | if (!priv) | 1301 | if (!priv) |
@@ -1247,60 +1310,16 @@ static int __devinit sci_probe(struct platform_device *dev) | |||
1247 | cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); | 1310 | cpufreq_register_notifier(&priv->clk_nb, CPUFREQ_TRANSITION_NOTIFIER); |
1248 | #endif | 1311 | #endif |
1249 | 1312 | ||
1250 | for (i = 0; p && p->flags != 0; p++, i++) { | 1313 | if (dev->id != -1) { |
1251 | struct sci_port *sciport = &sci_ports[i]; | 1314 | ret = sci_probe_single(dev, dev->id, p, &sci_ports[dev->id]); |
1252 | 1315 | if (ret) | |
1253 | /* Sanity check */ | ||
1254 | if (unlikely(i == SCI_NPORTS)) { | ||
1255 | dev_notice(&dev->dev, "Attempting to register port " | ||
1256 | "%d when only %d are available.\n", | ||
1257 | i+1, SCI_NPORTS); | ||
1258 | dev_notice(&dev->dev, "Consider bumping " | ||
1259 | "CONFIG_SERIAL_SH_SCI_NR_UARTS!\n"); | ||
1260 | break; | ||
1261 | } | ||
1262 | |||
1263 | sciport->port.mapbase = p->mapbase; | ||
1264 | |||
1265 | if (p->mapbase && !p->membase) { | ||
1266 | if (p->flags & UPF_IOREMAP) { | ||
1267 | p->membase = ioremap_nocache(p->mapbase, 0x40); | ||
1268 | if (IS_ERR(p->membase)) { | ||
1269 | ret = PTR_ERR(p->membase); | ||
1270 | goto err_unreg; | ||
1271 | } | ||
1272 | } else { | ||
1273 | /* | ||
1274 | * For the simple (and majority of) cases | ||
1275 | * where we don't need to do any remapping, | ||
1276 | * just cast the cookie directly. | ||
1277 | */ | ||
1278 | p->membase = (void __iomem *)p->mapbase; | ||
1279 | } | ||
1280 | } | ||
1281 | |||
1282 | sciport->port.membase = p->membase; | ||
1283 | |||
1284 | sciport->port.irq = p->irqs[SCIx_TXI_IRQ]; | ||
1285 | sciport->port.flags = p->flags; | ||
1286 | sciport->port.dev = &dev->dev; | ||
1287 | |||
1288 | sciport->type = sciport->port.type = p->type; | ||
1289 | |||
1290 | memcpy(&sciport->irqs, &p->irqs, sizeof(p->irqs)); | ||
1291 | |||
1292 | ret = uart_add_one_port(&sci_uart_driver, &sciport->port); | ||
1293 | |||
1294 | if (ret && (p->flags & UPF_IOREMAP)) { | ||
1295 | iounmap(p->membase); | ||
1296 | goto err_unreg; | 1316 | goto err_unreg; |
1317 | } else { | ||
1318 | for (i = 0; p && p->flags != 0; p++, i++) { | ||
1319 | ret = sci_probe_single(dev, i, p, &sci_ports[i]); | ||
1320 | if (ret) | ||
1321 | goto err_unreg; | ||
1297 | } | 1322 | } |
1298 | |||
1299 | INIT_LIST_HEAD(&sciport->node); | ||
1300 | |||
1301 | spin_lock_irqsave(&priv->lock, flags); | ||
1302 | list_add(&sciport->node, &priv->ports); | ||
1303 | spin_unlock_irqrestore(&priv->lock, flags); | ||
1304 | } | 1323 | } |
1305 | 1324 | ||
1306 | #ifdef CONFIG_SH_STANDARD_BIOS | 1325 | #ifdef CONFIG_SH_STANDARD_BIOS |