Merge branch 'for-2.6.25' of master.kernel.org:/pub/scm/linux/kernel/git/olof/pasemi into for-2.6.25

This commit is contained in:
Paul Mackerras 2008-01-17 16:17:58 +11:00
commit 52920df4aa
11 changed files with 255 additions and 208 deletions

View File

@ -1,7 +1,7 @@
# #
# Automatically generated make config: don't edit # Automatically generated make config: don't edit
# Linux kernel version: 2.6.24-rc6 # Linux kernel version: 2.6.24-rc6
# Fri Dec 28 11:01:53 2007 # Tue Jan 15 10:26:10 2008
# #
CONFIG_PPC64=y CONFIG_PPC64=y
@ -152,7 +152,6 @@ CONFIG_PPC_PASEMI=y
CONFIG_PPC_PASEMI_IOMMU=y CONFIG_PPC_PASEMI_IOMMU=y
# CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set # CONFIG_PPC_PASEMI_IOMMU_DMA_FORCE is not set
CONFIG_PPC_PASEMI_MDIO=y CONFIG_PPC_PASEMI_MDIO=y
CONFIG_ELECTRA_IDE=y
# CONFIG_PPC_CELLEB is not set # CONFIG_PPC_CELLEB is not set
# CONFIG_PPC_PS3 is not set # CONFIG_PPC_PS3 is not set
# CONFIG_PPC_CELL is not set # CONFIG_PPC_CELL is not set
@ -663,6 +662,7 @@ CONFIG_PATA_PCMCIA=y
# CONFIG_PATA_VIA is not set # CONFIG_PATA_VIA is not set
# CONFIG_PATA_WINBOND is not set # CONFIG_PATA_WINBOND is not set
CONFIG_PATA_PLATFORM=y CONFIG_PATA_PLATFORM=y
CONFIG_PATA_OF_PLATFORM=y
CONFIG_MD=y CONFIG_MD=y
CONFIG_BLK_DEV_MD=y CONFIG_BLK_DEV_MD=y
CONFIG_MD_LINEAR=y CONFIG_MD_LINEAR=y

View File

@ -37,13 +37,4 @@ config PPC_PASEMI_MDIO
help help
Driver for MDIO via GPIO on PWRficient platforms Driver for MDIO via GPIO on PWRficient platforms
config ELECTRA_IDE
tristate "Electra IDE driver"
default y
depends on PPC_PASEMI && ATA
select PATA_PLATFORM
help
This includes driver support for the Electra on-board IDE
interface.
endmenu endmenu

View File

@ -1,4 +1,3 @@
obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o obj-y += setup.o pci.o time.o idle.o powersave.o iommu.o
obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o obj-$(CONFIG_PPC_PASEMI_MDIO) += gpio_mdio.o
obj-$(CONFIG_ELECTRA_IDE) += electra_ide.o
obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o obj-$(CONFIG_PPC_PASEMI_CPUFREQ) += cpufreq.o

View File

@ -1,96 +0,0 @@
/*
* Copyright (C) 2007 PA Semi, Inc
*
* Maintained by: Olof Johansson <olof@lixom.net>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/platform_device.h>
#include <asm/prom.h>
#include <asm/system.h>
/* The electra IDE interface is incredibly simple: Just a device on the localbus
* with interrupts hooked up to one of the GPIOs. The device tree contains the
* address window and interrupt mappings already, and the pata_platform driver handles
* the rest. We just need to hook the two up.
*/
#define MAX_IFS 4 /* really, we have only one */
static struct platform_device *pdevs[MAX_IFS];
static int __devinit electra_ide_init(void)
{
struct device_node *np;
struct resource r[3];
int ret = 0;
int i;
np = of_find_compatible_node(NULL, "ide", "electra-ide");
i = 0;
while (np && i < MAX_IFS) {
memset(r, 0, sizeof(r));
/* pata_platform wants two address ranges: one for the base registers,
* another for the control (altstatus). It's located at offset 0x3f6 in
* the window, but the device tree only has one large register window
* that covers both ranges. So we need to split it up by hand here:
*/
ret = of_address_to_resource(np, 0, &r[0]);
if (ret)
goto out;
ret = of_address_to_resource(np, 0, &r[1]);
if (ret)
goto out;
r[1].start += 0x3f6;
r[0].end = r[1].start-1;
r[2].start = irq_of_parse_and_map(np, 0);
r[2].end = irq_of_parse_and_map(np, 0);
r[2].flags = IORESOURCE_IRQ;
pr_debug("registering platform device at 0x%lx/0x%lx, irq is %ld\n",
r[0].start, r[1].start, r[2].start);
pdevs[i] = platform_device_register_simple("pata_platform", i, r, 3);
if (IS_ERR(pdevs[i])) {
ret = PTR_ERR(pdevs[i]);
pdevs[i] = NULL;
goto out;
}
np = of_find_compatible_node(np, "ide", "electra-ide");
}
out:
return ret;
}
module_init(electra_ide_init);
static void __devexit electra_ide_exit(void)
{
int i;
for (i = 0; i < MAX_IFS; i++)
if (pdevs[i])
platform_device_unregister(pdevs[i]);
}
module_exit(electra_ide_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR ("Olof Johansson <olof@lixom.net>");
MODULE_DESCRIPTION("PA Semi Electra IDE driver");

View File

@ -74,9 +74,6 @@ static int pasemi_system_reset_exception(struct pt_regs *regs)
static int __init pasemi_idle_init(void) static int __init pasemi_idle_init(void)
{ {
if (!machine_is(pasemi))
return -ENODEV;
#ifndef CONFIG_PPC_PASEMI_CPUFREQ #ifndef CONFIG_PPC_PASEMI_CPUFREQ
printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n"); printk(KERN_WARNING "No cpufreq driver, powersavings modes disabled\n");
current_mode = 0; current_mode = 0;
@ -88,7 +85,7 @@ static int __init pasemi_idle_init(void)
return 0; return 0;
} }
late_initcall(pasemi_idle_init); machine_late_initcall(pasemi, pasemi_idle_init);
static int __init idle_param(char *p) static int __init idle_param(char *p)
{ {

View File

@ -135,9 +135,6 @@ static int __init pas_setup_mce_regs(void)
struct pci_dev *dev; struct pci_dev *dev;
int reg; int reg;
if (!machine_is(pasemi))
return -ENODEV;
/* Remap various SoC status registers for use by the MCE handler */ /* Remap various SoC status registers for use by the MCE handler */
reg = 0; reg = 0;
@ -181,7 +178,7 @@ static int __init pas_setup_mce_regs(void)
return 0; return 0;
} }
device_initcall(pas_setup_mce_regs); machine_device_initcall(pasemi, pas_setup_mce_regs);
static __init void pas_init_IRQ(void) static __init void pas_init_IRQ(void)
{ {
@ -264,7 +261,7 @@ static int pas_machine_check_handler(struct pt_regs *regs)
srr0 = regs->nip; srr0 = regs->nip;
srr1 = regs->msr; srr1 = regs->msr;
if (mpic_get_mcirq() == nmi_virq) { if (nmi_virq != NO_IRQ && mpic_get_mcirq() == nmi_virq) {
printk(KERN_ERR "NMI delivered\n"); printk(KERN_ERR "NMI delivered\n");
debugger(regs); debugger(regs);
mpic_end_irq(nmi_virq); mpic_end_irq(nmi_virq);
@ -405,9 +402,6 @@ static struct of_device_id pasemi_bus_ids[] = {
static int __init pasemi_publish_devices(void) static int __init pasemi_publish_devices(void)
{ {
if (!machine_is(pasemi))
return 0;
pasemi_pcmcia_init(); pasemi_pcmcia_init();
/* Publish OF platform devices for SDC and other non-PCI devices */ /* Publish OF platform devices for SDC and other non-PCI devices */
@ -415,7 +409,7 @@ static int __init pasemi_publish_devices(void)
return 0; return 0;
} }
device_initcall(pasemi_publish_devices); machine_device_initcall(pasemi, pasemi_publish_devices);
/* /*

View File

@ -607,13 +607,23 @@ config PATA_WINBOND_VLB
config PATA_PLATFORM config PATA_PLATFORM
tristate "Generic platform device PATA support" tristate "Generic platform device PATA support"
depends on EMBEDDED || ARCH_RPC depends on EMBEDDED || ARCH_RPC || PPC
help help
This option enables support for generic directly connected ATA This option enables support for generic directly connected ATA
devices commonly found on embedded systems. devices commonly found on embedded systems.
If unsure, say N. If unsure, say N.
config PATA_OF_PLATFORM
tristate "OpenFirmware platform device PATA support"
depends on PATA_PLATFORM && PPC_OF
help
This option enables support for generic directly connected ATA
devices commonly found on embedded systems with OpenFirmware
bindings.
If unsure, say N.
config PATA_ICSIDE config PATA_ICSIDE
tristate "Acorn ICS PATA support" tristate "Acorn ICS PATA support"
depends on ARM && ARCH_ACORN depends on ARM && ARCH_ACORN

View File

@ -67,6 +67,7 @@ obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
obj-$(CONFIG_PATA_SCC) += pata_scc.o obj-$(CONFIG_PATA_SCC) += pata_scc.o
obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o obj-$(CONFIG_PATA_BF54X) += pata_bf54x.o
obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
obj-$(CONFIG_PATA_OF_PLATFORM) += pata_of_platform.o
obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o obj-$(CONFIG_PATA_ICSIDE) += pata_icside.o
# Should be last but two libata driver # Should be last but two libata driver
obj-$(CONFIG_PATA_ACPI) += pata_acpi.o obj-$(CONFIG_PATA_ACPI) += pata_acpi.o

View File

@ -0,0 +1,114 @@
/*
* OF-platform PATA driver
*
* Copyright (c) 2007 MontaVista Software, Inc.
* Anton Vorontsov <avorontsov@ru.mvista.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (Version 2) as
* published by the Free Software Foundation.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of_platform.h>
#include <linux/pata_platform.h>
static int __devinit pata_of_platform_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
int ret;
struct device_node *dn = ofdev->node;
struct resource io_res;
struct resource ctl_res;
struct resource irq_res;
unsigned int reg_shift = 0;
int pio_mode = 0;
int pio_mask;
const u32 *prop;
ret = of_address_to_resource(dn, 0, &io_res);
if (ret) {
dev_err(&ofdev->dev, "can't get IO address from "
"device tree\n");
return -EINVAL;
}
if (of_device_is_compatible(dn, "electra-ide")) {
/* Altstatus is really at offset 0x3f6 from the primary window
* on electra-ide. Adjust ctl_res and io_res accordingly.
*/
ctl_res = io_res;
ctl_res.start = ctl_res.start+0x3f6;
io_res.end = ctl_res.start-1;
} else {
ret = of_address_to_resource(dn, 1, &ctl_res);
if (ret) {
dev_err(&ofdev->dev, "can't get CTL address from "
"device tree\n");
return -EINVAL;
}
}
ret = of_irq_to_resource(dn, 0, &irq_res);
if (ret == NO_IRQ)
irq_res.start = irq_res.end = -1;
else
irq_res.flags = 0;
prop = of_get_property(dn, "reg-shift", NULL);
if (prop)
reg_shift = *prop;
prop = of_get_property(dn, "pio-mode", NULL);
if (prop) {
pio_mode = *prop;
if (pio_mode > 6) {
dev_err(&ofdev->dev, "invalid pio-mode\n");
return -EINVAL;
}
} else {
dev_info(&ofdev->dev, "pio-mode unspecified, assuming PIO0\n");
}
pio_mask = 1 << pio_mode;
pio_mask |= (1 << pio_mode) - 1;
return __pata_platform_probe(&ofdev->dev, &io_res, &ctl_res, &irq_res,
reg_shift, pio_mask);
}
static int __devexit pata_of_platform_remove(struct of_device *ofdev)
{
return __pata_platform_remove(&ofdev->dev);
}
static struct of_device_id pata_of_platform_match[] = {
{ .compatible = "ata-generic", },
{ .compatible = "electra-ide", },
{},
};
MODULE_DEVICE_TABLE(of, pata_of_platform_match);
static struct of_platform_driver pata_of_platform_driver = {
.name = "pata_of_platform",
.match_table = pata_of_platform_match,
.probe = pata_of_platform_probe,
.remove = __devexit_p(pata_of_platform_remove),
};
static int __init pata_of_platform_init(void)
{
return of_register_platform_driver(&pata_of_platform_driver);
}
module_init(pata_of_platform_init);
static void __exit pata_of_platform_exit(void)
{
of_unregister_platform_driver(&pata_of_platform_driver);
}
module_exit(pata_of_platform_exit);
MODULE_DESCRIPTION("OF-platform PATA driver");
MODULE_AUTHOR("Anton Vorontsov <avorontsov@ru.mvista.com>");
MODULE_LICENSE("GPL");

View File

@ -93,14 +93,9 @@ static struct ata_port_operations pata_platform_port_ops = {
}; };
static void pata_platform_setup_port(struct ata_ioports *ioaddr, static void pata_platform_setup_port(struct ata_ioports *ioaddr,
struct pata_platform_info *info) unsigned int shift)
{ {
unsigned int shift = 0;
/* Fixup the port shift for platforms that need it */ /* Fixup the port shift for platforms that need it */
if (info && info->ioport_shift)
shift = info->ioport_shift;
ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift); ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift);
ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift); ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift);
ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift); ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift);
@ -114,8 +109,13 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
} }
/** /**
* pata_platform_probe - attach a platform interface * __pata_platform_probe - attach a platform interface
* @pdev: platform device * @dev: device
* @io_res: Resource representing I/O base
* @ctl_res: Resource representing CTL base
* @irq_res: Resource representing IRQ and its flags
* @ioport_shift: I/O port shift
* @__pio_mask: PIO mask
* *
* Register a platform bus IDE interface. Such interfaces are PIO and we * Register a platform bus IDE interface. Such interfaces are PIO and we
* assume do not support IRQ sharing. * assume do not support IRQ sharing.
@ -135,14 +135,109 @@ static void pata_platform_setup_port(struct ata_ioports *ioaddr,
* *
* If no IRQ resource is present, PIO polling mode is used instead. * If no IRQ resource is present, PIO polling mode is used instead.
*/ */
static int __devinit pata_platform_probe(struct platform_device *pdev) int __devinit __pata_platform_probe(struct device *dev,
struct resource *io_res,
struct resource *ctl_res,
struct resource *irq_res,
unsigned int ioport_shift,
int __pio_mask)
{ {
struct resource *io_res, *ctl_res;
struct ata_host *host; struct ata_host *host;
struct ata_port *ap; struct ata_port *ap;
struct pata_platform_info *pp_info;
unsigned int mmio; unsigned int mmio;
int irq; int irq = 0;
int irq_flags = 0;
/*
* Check for MMIO
*/
mmio = (( io_res->flags == IORESOURCE_MEM) &&
(ctl_res->flags == IORESOURCE_MEM));
/*
* And the IRQ
*/
if (irq_res && irq_res->start > 0) {
irq = irq_res->start;
irq_flags = irq_res->flags;
}
/*
* Now that that's out of the way, wire up the port..
*/
host = ata_host_alloc(dev, 1);
if (!host)
return -ENOMEM;
ap = host->ports[0];
ap->ops = &pata_platform_port_ops;
ap->pio_mask = __pio_mask;
ap->flags |= ATA_FLAG_SLAVE_POSS;
/*
* Use polling mode if there's no IRQ
*/
if (!irq) {
ap->flags |= ATA_FLAG_PIO_POLLING;
ata_port_desc(ap, "no IRQ, using PIO polling");
}
/*
* Handle the MMIO case
*/
if (mmio) {
ap->ioaddr.cmd_addr = devm_ioremap(dev, io_res->start,
io_res->end - io_res->start + 1);
ap->ioaddr.ctl_addr = devm_ioremap(dev, ctl_res->start,
ctl_res->end - ctl_res->start + 1);
} else {
ap->ioaddr.cmd_addr = devm_ioport_map(dev, io_res->start,
io_res->end - io_res->start + 1);
ap->ioaddr.ctl_addr = devm_ioport_map(dev, ctl_res->start,
ctl_res->end - ctl_res->start + 1);
}
if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) {
dev_err(dev, "failed to map IO/CTL base\n");
return -ENOMEM;
}
ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
pata_platform_setup_port(&ap->ioaddr, ioport_shift);
ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport",
(unsigned long long)io_res->start,
(unsigned long long)ctl_res->start);
/* activate */
return ata_host_activate(host, irq, irq ? ata_interrupt : NULL,
irq_flags, &pata_platform_sht);
}
EXPORT_SYMBOL_GPL(__pata_platform_probe);
/**
* __pata_platform_remove - unplug a platform interface
* @dev: device
*
* A platform bus ATA device has been unplugged. Perform the needed
* cleanup. Also called on module unload for any active devices.
*/
int __devexit __pata_platform_remove(struct device *dev)
{
struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host);
return 0;
}
EXPORT_SYMBOL_GPL(__pata_platform_remove);
static int __devinit pata_platform_probe(struct platform_device *pdev)
{
struct resource *io_res;
struct resource *ctl_res;
struct resource *irq_res;
struct pata_platform_info *pp_info = pdev->dev.platform_data;
/* /*
* Simple resource validation .. * Simple resource validation ..
@ -172,88 +267,21 @@ static int __devinit pata_platform_probe(struct platform_device *pdev)
return -EINVAL; return -EINVAL;
} }
/*
* Check for MMIO
*/
mmio = (( io_res->flags == IORESOURCE_MEM) &&
(ctl_res->flags == IORESOURCE_MEM));
/* /*
* And the IRQ * And the IRQ
*/ */
irq = platform_get_irq(pdev, 0); irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
if (irq < 0) if (irq_res)
irq = 0; /* no irq */ irq_res->flags = pp_info ? pp_info->irq_flags : 0;
/* return __pata_platform_probe(&pdev->dev, io_res, ctl_res, irq_res,
* Now that that's out of the way, wire up the port.. pp_info ? pp_info->ioport_shift : 0,
*/ pio_mask);
host = ata_host_alloc(&pdev->dev, 1);
if (!host)
return -ENOMEM;
ap = host->ports[0];
ap->ops = &pata_platform_port_ops;
ap->pio_mask = pio_mask;
ap->flags |= ATA_FLAG_SLAVE_POSS;
/*
* Use polling mode if there's no IRQ
*/
if (!irq) {
ap->flags |= ATA_FLAG_PIO_POLLING;
ata_port_desc(ap, "no IRQ, using PIO polling");
}
/*
* Handle the MMIO case
*/
if (mmio) {
ap->ioaddr.cmd_addr = devm_ioremap(&pdev->dev, io_res->start,
io_res->end - io_res->start + 1);
ap->ioaddr.ctl_addr = devm_ioremap(&pdev->dev, ctl_res->start,
ctl_res->end - ctl_res->start + 1);
} else {
ap->ioaddr.cmd_addr = devm_ioport_map(&pdev->dev, io_res->start,
io_res->end - io_res->start + 1);
ap->ioaddr.ctl_addr = devm_ioport_map(&pdev->dev, ctl_res->start,
ctl_res->end - ctl_res->start + 1);
}
if (!ap->ioaddr.cmd_addr || !ap->ioaddr.ctl_addr) {
dev_err(&pdev->dev, "failed to map IO/CTL base\n");
return -ENOMEM;
}
ap->ioaddr.altstatus_addr = ap->ioaddr.ctl_addr;
pp_info = pdev->dev.platform_data;
pata_platform_setup_port(&ap->ioaddr, pp_info);
ata_port_desc(ap, "%s cmd 0x%llx ctl 0x%llx", mmio ? "mmio" : "ioport",
(unsigned long long)io_res->start,
(unsigned long long)ctl_res->start);
/* activate */
return ata_host_activate(host, irq, irq ? ata_interrupt : NULL,
pp_info ? pp_info->irq_flags : 0,
&pata_platform_sht);
} }
/**
* pata_platform_remove - unplug a platform interface
* @pdev: platform device
*
* A platform bus ATA device has been unplugged. Perform the needed
* cleanup. Also called on module unload for any active devices.
*/
static int __devexit pata_platform_remove(struct platform_device *pdev) static int __devexit pata_platform_remove(struct platform_device *pdev)
{ {
struct device *dev = &pdev->dev; return __pata_platform_remove(&pdev->dev);
struct ata_host *host = dev_get_drvdata(dev);
ata_host_detach(host);
return 0;
} }
static struct platform_driver pata_platform_driver = { static struct platform_driver pata_platform_driver = {

View File

@ -15,4 +15,13 @@ struct pata_platform_info {
unsigned int irq_flags; unsigned int irq_flags;
}; };
extern int __devinit __pata_platform_probe(struct device *dev,
struct resource *io_res,
struct resource *ctl_res,
struct resource *irq_res,
unsigned int ioport_shift,
int __pio_mask);
extern int __devexit __pata_platform_remove(struct device *dev);
#endif /* __LINUX_PATA_PLATFORM_H */ #endif /* __LINUX_PATA_PLATFORM_H */