diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-16 12:08:13 -0700 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-09-16 12:08:13 -0700 |
commit | cac4662a88702fc9e405ef19c429de375822d77a (patch) | |
tree | 8de362ab63366e281843351a37daf162f10cb888 /drivers | |
parent | 22f6b4d34fcf039c63a94e7670e0da24f8575a5a (diff) | |
parent | 1a57c286d8ced1e4144c6201a19bbb70827edee6 (diff) | |
download | linux-cac4662a88702fc9e405ef19c429de375822d77a.tar.bz2 |
Merge branch 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm
Pull ARM fixes from Russell King:
"Most of this update are fixes primarily discovered from testing on the
older StrongARM 1110 and PXA systems, as a result of recent interest
from several people in these platforms:
- Locomo interrupt handling incorrectly stores the handler data in
the chip's private data slot: when Locomo is combined with an
interrupt controller who's chip uses the chip private data, this
leads to an oops.
- SA1111 was missing a call to clk_disable() to clean up after a
failed probe.
- SA1111 and PCMCIA suspend/resume was broken:
The PCMCIA "ds" layer was using the legacy bus suspend/resume
methods, which the core PM code is no longer calling as a result of
device_pm_check_callbacks() introduced in commit aa8e54b559479
("PM / sleep: Go direct_complete if driver has no callbacks").
SA1111 was broken due to changes to PCMCIA which makes PCMCIA
suspend itself later than the SA1111 code expects, and resume
before the SA1111 code has initialised access to the pcmcia
sub-device.
- the default SA1111 interrupt mask polarity got messed up when it
was converted to use a dynamic interrupt base number for its
interrupts.
- fix platform_get_irq() error code propagation, which was causing
problems on platforms where the interrupt may not be available at
probe time in DT setups.
- fix the lack of clock to PCMCIA code on PXA platforms, which was
omitted in conversions of PXA to CCF.
- fix an oops in the PXA PCMCIA code caused by a previous commit not
realising that Lubbock is different from the rest of the PXA PCMCIA
drivers.
- ensure that SA1111 low-level PCMCIA drivers propagate their error
codes to the main probe function, rather than the driver silently
accepting a failure.
- fix the sa11xx debugfs reporting of timing information, which
always indicated zero due to the clock being a factor of 1000 out.
- fix the polarity of the status change signal reported from the
sockets.
Lastly, one ARM specific commit from Stefan Agner fixing the LPAE
cache attributes"
* 'fixes' of git://git.armlinux.org.uk/~rmk/linux-arm:
ARM: pxa/lubbock: add pcmcia clock
ARM: locomo: fix locomo irq handling
ARM: 8612/1: LPAE: initialize cache policy correctly
ARM: sa1111: fix missing clk_disable()
ARM: sa1111: fix pcmcia suspend/resume
ARM: sa1111: fix pcmcia interrupt mask polarity
ARM: sa1111: fix error code propagation in sa1111_probe()
pcmcia: lubbock: fix sockets configuration
pcmcia: sa1111: fix propagation of lowlevel board init return code
pcmcia: soc_common: fix SS_STSCHG polarity
pcmcia: sa11xx_base: add units to the timing information
pcmcia: sa11xx_base: fix reporting of timing information
pcmcia: ds: fix suspend/resume
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/pcmcia/ds.c | 12 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_base.c | 9 | ||||
-rw-r--r-- | drivers/pcmcia/pxa2xx_base.h | 2 | ||||
-rw-r--r-- | drivers/pcmcia/sa1111_badge4.c | 22 | ||||
-rw-r--r-- | drivers/pcmcia/sa1111_generic.c | 22 | ||||
-rw-r--r-- | drivers/pcmcia/sa1111_jornada720.c | 25 | ||||
-rw-r--r-- | drivers/pcmcia/sa1111_lubbock.c | 32 | ||||
-rw-r--r-- | drivers/pcmcia/sa1111_neponset.c | 26 | ||||
-rw-r--r-- | drivers/pcmcia/sa11xx_base.c | 8 | ||||
-rw-r--r-- | drivers/pcmcia/soc_common.c | 2 |
10 files changed, 76 insertions, 84 deletions
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c index 489ea1098c96..69b5e811ea2b 100644 --- a/drivers/pcmcia/ds.c +++ b/drivers/pcmcia/ds.c @@ -977,7 +977,7 @@ static int pcmcia_bus_uevent(struct device *dev, struct kobj_uevent_env *env) /************************ runtime PM support ***************************/ -static int pcmcia_dev_suspend(struct device *dev, pm_message_t state); +static int pcmcia_dev_suspend(struct device *dev); static int pcmcia_dev_resume(struct device *dev); static int runtime_suspend(struct device *dev) @@ -985,7 +985,7 @@ static int runtime_suspend(struct device *dev) int rc; device_lock(dev); - rc = pcmcia_dev_suspend(dev, PMSG_SUSPEND); + rc = pcmcia_dev_suspend(dev); device_unlock(dev); return rc; } @@ -1135,7 +1135,7 @@ ATTRIBUTE_GROUPS(pcmcia_dev); /* PM support, also needed for reset */ -static int pcmcia_dev_suspend(struct device *dev, pm_message_t state) +static int pcmcia_dev_suspend(struct device *dev) { struct pcmcia_device *p_dev = to_pcmcia_dev(dev); struct pcmcia_driver *p_drv = NULL; @@ -1410,6 +1410,9 @@ static struct class_interface pcmcia_bus_interface __refdata = { .remove_dev = &pcmcia_bus_remove_socket, }; +static const struct dev_pm_ops pcmcia_bus_pm_ops = { + SET_SYSTEM_SLEEP_PM_OPS(pcmcia_dev_suspend, pcmcia_dev_resume) +}; struct bus_type pcmcia_bus_type = { .name = "pcmcia", @@ -1418,8 +1421,7 @@ struct bus_type pcmcia_bus_type = { .dev_groups = pcmcia_dev_groups, .probe = pcmcia_device_probe, .remove = pcmcia_device_remove, - .suspend = pcmcia_dev_suspend, - .resume = pcmcia_dev_resume, + .pm = &pcmcia_bus_pm_ops, }; diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c index 483f919e0d2e..91b5f5724cba 100644 --- a/drivers/pcmcia/pxa2xx_base.c +++ b/drivers/pcmcia/pxa2xx_base.c @@ -214,9 +214,8 @@ pxa2xx_pcmcia_frequency_change(struct soc_pcmcia_socket *skt, } #endif -void pxa2xx_configure_sockets(struct device *dev) +void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops) { - struct pcmcia_low_level *ops = dev->platform_data; /* * We have at least one socket, so set MECR:CIT * (Card Is There) @@ -322,7 +321,7 @@ static int pxa2xx_drv_pcmcia_probe(struct platform_device *dev) goto err1; } - pxa2xx_configure_sockets(&dev->dev); + pxa2xx_configure_sockets(&dev->dev, ops); dev_set_drvdata(&dev->dev, sinfo); return 0; @@ -348,7 +347,9 @@ static int pxa2xx_drv_pcmcia_remove(struct platform_device *dev) static int pxa2xx_drv_pcmcia_resume(struct device *dev) { - pxa2xx_configure_sockets(dev); + struct pcmcia_low_level *ops = (struct pcmcia_low_level *)dev->platform_data; + + pxa2xx_configure_sockets(dev, ops); return 0; } diff --git a/drivers/pcmcia/pxa2xx_base.h b/drivers/pcmcia/pxa2xx_base.h index b609b45469ed..e58c7a415418 100644 --- a/drivers/pcmcia/pxa2xx_base.h +++ b/drivers/pcmcia/pxa2xx_base.h @@ -1,4 +1,4 @@ int pxa2xx_drv_pcmcia_add_one(struct soc_pcmcia_socket *skt); void pxa2xx_drv_pcmcia_ops(struct pcmcia_low_level *ops); -void pxa2xx_configure_sockets(struct device *dev); +void pxa2xx_configure_sockets(struct device *dev, struct pcmcia_low_level *ops); diff --git a/drivers/pcmcia/sa1111_badge4.c b/drivers/pcmcia/sa1111_badge4.c index 12f0dd091477..2f490930430d 100644 --- a/drivers/pcmcia/sa1111_badge4.c +++ b/drivers/pcmcia/sa1111_badge4.c @@ -134,20 +134,14 @@ static struct pcmcia_low_level badge4_pcmcia_ops = { int pcmcia_badge4_init(struct sa1111_dev *dev) { - int ret = -ENODEV; - - if (machine_is_badge4()) { - printk(KERN_INFO - "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n", - __func__, - badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); - - sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); - ret = sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, - sa11xx_drv_pcmcia_add_one); - } - - return ret; + printk(KERN_INFO + "%s: badge4_pcmvcc=%d, badge4_pcmvpp=%d, badge4_cfvcc=%d\n", + __func__, + badge4_pcmvcc, badge4_pcmvpp, badge4_cfvcc); + + sa11xx_drv_pcmcia_ops(&badge4_pcmcia_ops); + return sa1111_pcmcia_add(dev, &badge4_pcmcia_ops, + sa11xx_drv_pcmcia_add_one); } static int __init pcmv_setup(char *s) diff --git a/drivers/pcmcia/sa1111_generic.c b/drivers/pcmcia/sa1111_generic.c index a1531feb8460..3d95dffcff7a 100644 --- a/drivers/pcmcia/sa1111_generic.c +++ b/drivers/pcmcia/sa1111_generic.c @@ -18,6 +18,7 @@ #include <mach/hardware.h> #include <asm/hardware/sa1111.h> +#include <asm/mach-types.h> #include <asm/irq.h> #include "sa1111_generic.h" @@ -203,19 +204,30 @@ static int pcmcia_probe(struct sa1111_dev *dev) sa1111_writel(PCSSR_S0_SLEEP | PCSSR_S1_SLEEP, base + PCSSR); sa1111_writel(PCCR_S0_FLT | PCCR_S1_FLT, base + PCCR); + ret = -ENODEV; #ifdef CONFIG_SA1100_BADGE4 - pcmcia_badge4_init(dev); + if (machine_is_badge4()) + ret = pcmcia_badge4_init(dev); #endif #ifdef CONFIG_SA1100_JORNADA720 - pcmcia_jornada720_init(dev); + if (machine_is_jornada720()) + ret = pcmcia_jornada720_init(dev); #endif #ifdef CONFIG_ARCH_LUBBOCK - pcmcia_lubbock_init(dev); + if (machine_is_lubbock()) + ret = pcmcia_lubbock_init(dev); #endif #ifdef CONFIG_ASSABET_NEPONSET - pcmcia_neponset_init(dev); + if (machine_is_assabet()) + ret = pcmcia_neponset_init(dev); #endif - return 0; + + if (ret) { + release_mem_region(dev->res.start, 512); + sa1111_disable_device(dev); + } + + return ret; } static int pcmcia_remove(struct sa1111_dev *dev) diff --git a/drivers/pcmcia/sa1111_jornada720.c b/drivers/pcmcia/sa1111_jornada720.c index c2c30580c83f..480a3ede27c8 100644 --- a/drivers/pcmcia/sa1111_jornada720.c +++ b/drivers/pcmcia/sa1111_jornada720.c @@ -94,22 +94,17 @@ static struct pcmcia_low_level jornada720_pcmcia_ops = { int pcmcia_jornada720_init(struct sa1111_dev *sadev) { - int ret = -ENODEV; + unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; - if (machine_is_jornada720()) { - unsigned int pin = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; + /* Fixme: why messing around with SA11x0's GPIO1? */ + GRER |= 0x00000002; - GRER |= 0x00000002; + /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ + sa1111_set_io_dir(sadev, pin, 0, 0); + sa1111_set_io(sadev, pin, 0); + sa1111_set_sleep_io(sadev, pin, 0); - /* Set GPIO_A<3:1> to be outputs for PCMCIA/CF power controller: */ - sa1111_set_io_dir(sadev, pin, 0, 0); - sa1111_set_io(sadev, pin, 0); - sa1111_set_sleep_io(sadev, pin, 0); - - sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); - ret = sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops, - sa11xx_drv_pcmcia_add_one); - } - - return ret; + sa11xx_drv_pcmcia_ops(&jornada720_pcmcia_ops); + return sa1111_pcmcia_add(sadev, &jornada720_pcmcia_ops, + sa11xx_drv_pcmcia_add_one); } diff --git a/drivers/pcmcia/sa1111_lubbock.c b/drivers/pcmcia/sa1111_lubbock.c index c5caf5790451..e741f499c875 100644 --- a/drivers/pcmcia/sa1111_lubbock.c +++ b/drivers/pcmcia/sa1111_lubbock.c @@ -210,27 +210,21 @@ static struct pcmcia_low_level lubbock_pcmcia_ops = { int pcmcia_lubbock_init(struct sa1111_dev *sadev) { - int ret = -ENODEV; - - if (machine_is_lubbock()) { - /* - * Set GPIO_A<3:0> to be outputs for the MAX1600, - * and switch to standby mode. - */ - sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); - sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); - sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); - - /* Set CF Socket 1 power to standby mode. */ - lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); + /* + * Set GPIO_A<3:0> to be outputs for the MAX1600, + * and switch to standby mode. + */ + sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); + sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); + sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); - pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); - pxa2xx_configure_sockets(&sadev->dev); - ret = sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, - pxa2xx_drv_pcmcia_add_one); - } + /* Set CF Socket 1 power to standby mode. */ + lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); - return ret; + pxa2xx_drv_pcmcia_ops(&lubbock_pcmcia_ops); + pxa2xx_configure_sockets(&sadev->dev, &lubbock_pcmcia_ops); + return sa1111_pcmcia_add(sadev, &lubbock_pcmcia_ops, + pxa2xx_drv_pcmcia_add_one); } MODULE_LICENSE("GPL"); diff --git a/drivers/pcmcia/sa1111_neponset.c b/drivers/pcmcia/sa1111_neponset.c index 1d78739c4c07..019c395eb4bf 100644 --- a/drivers/pcmcia/sa1111_neponset.c +++ b/drivers/pcmcia/sa1111_neponset.c @@ -110,20 +110,14 @@ static struct pcmcia_low_level neponset_pcmcia_ops = { int pcmcia_neponset_init(struct sa1111_dev *sadev) { - int ret = -ENODEV; - - if (machine_is_assabet()) { - /* - * Set GPIO_A<3:0> to be outputs for the MAX1600, - * and switch to standby mode. - */ - sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); - sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); - sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); - sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); - ret = sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, - sa11xx_drv_pcmcia_add_one); - } - - return ret; + /* + * Set GPIO_A<3:0> to be outputs for the MAX1600, + * and switch to standby mode. + */ + sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); + sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); + sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); + sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops); + return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops, + sa11xx_drv_pcmcia_add_one); } diff --git a/drivers/pcmcia/sa11xx_base.c b/drivers/pcmcia/sa11xx_base.c index 9f6ec87b9f9e..48140ac73ed6 100644 --- a/drivers/pcmcia/sa11xx_base.c +++ b/drivers/pcmcia/sa11xx_base.c @@ -144,19 +144,19 @@ static int sa1100_pcmcia_show_timing(struct soc_pcmcia_socket *skt, char *buf) { struct soc_pcmcia_timing timing; - unsigned int clock = clk_get_rate(skt->clk); + unsigned int clock = clk_get_rate(skt->clk) / 1000; unsigned long mecr = MECR; char *p = buf; soc_common_pcmcia_get_timing(skt, &timing); - p+=sprintf(p, "I/O : %u (%u)\n", timing.io, + p+=sprintf(p, "I/O : %uns (%uns)\n", timing.io, sa1100_pcmcia_cmd_time(clock, MECR_BSIO_GET(mecr, skt->nr))); - p+=sprintf(p, "attribute: %u (%u)\n", timing.attr, + p+=sprintf(p, "attribute: %uns (%uns)\n", timing.attr, sa1100_pcmcia_cmd_time(clock, MECR_BSA_GET(mecr, skt->nr))); - p+=sprintf(p, "common : %u (%u)\n", timing.mem, + p+=sprintf(p, "common : %uns (%uns)\n", timing.mem, sa1100_pcmcia_cmd_time(clock, MECR_BSM_GET(mecr, skt->nr))); return p - buf; diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c index eed5e9c05353..d5ca760c4eb2 100644 --- a/drivers/pcmcia/soc_common.c +++ b/drivers/pcmcia/soc_common.c @@ -235,7 +235,7 @@ static unsigned int soc_common_pcmcia_skt_state(struct soc_pcmcia_socket *skt) stat |= skt->cs_state.Vcc ? SS_POWERON : 0; if (skt->cs_state.flags & SS_IOCARD) - stat |= state.bvd1 ? SS_STSCHG : 0; + stat |= state.bvd1 ? 0 : SS_STSCHG; else { if (state.bvd1 == 0) stat |= SS_BATDEAD; |