From b7aaacf56ac9e0cdb58c3d087fea7084d897c307 Mon Sep 17 00:00:00 2001 From: Anton Vorontsov Date: Wed, 1 Feb 2012 21:20:15 +0400 Subject: Revert "bq27x00_battery: Fix reporting status value for bq27500 battery" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 270968c0984aeed096da3cfffb0e131f4c416166. Grazvydas Ignotas wrote: After 270968c0984ae "bq27x00_battery: Fix reporting status value for bq27500 battery" status doesn't seem to be reported correctly when the battery is close to fully charged state. It reports "Not charging" while in fact there is >130mA current flowing to the battery according to current_now. This status report seems to be based on CHG bit in status register, but looking at the datasheet the description says "(Fast) charging allowed", which I guess means that the chip recommends charging and not that charging is actually going on? If you check the bit while battery is discharging and it's not full, the bit is also set. Suggested-by: Grazvydas Ignotas Acked-by: Pali Rohár Signed-off-by: Anton Vorontsov --- drivers/power/bq27x00_battery.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index 98bf5676318d..d4b5281dea15 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -62,11 +62,10 @@ #define BQ27500_REG_SOC 0x2C #define BQ27500_REG_DCAP 0x3C /* Design capacity */ -#define BQ27500_FLAG_DSG BIT(0) /* Discharging */ +#define BQ27500_FLAG_DSC BIT(0) #define BQ27500_FLAG_SOCF BIT(1) /* State-of-Charge threshold final */ #define BQ27500_FLAG_SOC1 BIT(2) /* State-of-Charge threshold 1 */ -#define BQ27500_FLAG_CHG BIT(8) /* Charging */ -#define BQ27500_FLAG_FC BIT(9) /* Fully charged */ +#define BQ27500_FLAG_FC BIT(9) #define BQ27000_RS 20 /* Resistor sense */ @@ -401,14 +400,10 @@ static int bq27x00_battery_status(struct bq27x00_device_info *di, if (di->chip == BQ27500) { if (di->cache.flags & BQ27500_FLAG_FC) status = POWER_SUPPLY_STATUS_FULL; - else if (di->cache.flags & BQ27500_FLAG_DSG) + else if (di->cache.flags & BQ27500_FLAG_DSC) status = POWER_SUPPLY_STATUS_DISCHARGING; - else if (di->cache.flags & BQ27500_FLAG_CHG) - status = POWER_SUPPLY_STATUS_CHARGING; - else if (power_supply_am_i_supplied(&di->bat)) - status = POWER_SUPPLY_STATUS_NOT_CHARGING; else - status = POWER_SUPPLY_STATUS_UNKNOWN; + status = POWER_SUPPLY_STATUS_CHARGING; } else { if (di->cache.flags & BQ27000_FLAG_FC) status = POWER_SUPPLY_STATUS_FULL; -- cgit v1.2.3-59-g8ed1b From 4d4036591b3de279a8c93a3cb010b0bc1264703c Mon Sep 17 00:00:00 2001 From: Grazvydas Ignotas Date: Sat, 14 Jan 2012 22:50:49 +0200 Subject: bq27x00_battery: Fix flag register read MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When reading flags, bq27x00_read() argument is inverted and causes reads 2 of bytes for bq27200 and 1 byte for bq27500, while their register sizes are 1 and 2 bytes respectively. This causes bq27500 upper flag bits always to be returned as 0, causing full charge state to never be reported correctly, so fix it. Cc: Lars-Peter Clausen Signed-off-by: Grazvydas Ignotas Acked-by: Pali Rohár Signed-off-by: Anton Vorontsov --- drivers/power/bq27x00_battery.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/power/bq27x00_battery.c b/drivers/power/bq27x00_battery.c index d4b5281dea15..1ed6ea0bad6e 100644 --- a/drivers/power/bq27x00_battery.c +++ b/drivers/power/bq27x00_battery.c @@ -311,7 +311,7 @@ static void bq27x00_update(struct bq27x00_device_info *di) struct bq27x00_reg_cache cache = {0, }; bool is_bq27500 = di->chip == BQ27500; - cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, is_bq27500); + cache.flags = bq27x00_read(di, BQ27x00_REG_FLAGS, !is_bq27500); if (cache.flags >= 0) { if (!is_bq27500 && (cache.flags & BQ27000_FLAG_CI)) { dev_info(di->dev, "battery is not calibrated! ignoring capacity values\n"); -- cgit v1.2.3-59-g8ed1b From 1bbe24d465db626fed050e0128a7244b9cb407f4 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Wed, 11 Jan 2012 17:19:45 +0800 Subject: power_supply: Fix modalias for charger-manager Since 43cc71eed1250755986da4c0f9898f9a635cb3bf, the platform modalias is prefixed with "platform:". Current code has the id_table, thus add MODULE_DEVICE_TABLE will automatically setup the modalias. Also make charger_manager_id static as it is only used in this driver. Signed-off-by: Axel Lin Acked-by: MyungJoo Ham Signed-off-by: Anton Vorontsov --- drivers/power/charger-manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/power/charger-manager.c b/drivers/power/charger-manager.c index 0378d019efae..88fd9710bda2 100644 --- a/drivers/power/charger-manager.c +++ b/drivers/power/charger-manager.c @@ -974,10 +974,11 @@ static int __devexit charger_manager_remove(struct platform_device *pdev) return 0; } -const struct platform_device_id charger_manager_id[] = { +static const struct platform_device_id charger_manager_id[] = { { "charger-manager", 0 }, { }, }; +MODULE_DEVICE_TABLE(platform, charger_manager_id); static int cm_suspend_prepare(struct device *dev) { @@ -1069,4 +1070,3 @@ module_exit(charger_manager_cleanup); MODULE_AUTHOR("MyungJoo Ham "); MODULE_DESCRIPTION("Charger Manager"); MODULE_LICENSE("GPL"); -MODULE_ALIAS("charger-manager"); -- cgit v1.2.3-59-g8ed1b From 455a0e2cd80f7a2849b2e6d3be85c053ee44446b Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Mon, 16 Jan 2012 13:48:20 +0800 Subject: lp8727_charger: Add terminating entry for i2c_device_id table The i2c_device_id table is supposed to be zero-terminated. Signed-off-by: Axel Lin Acked-by: Milo(Woogyom) Kim Signed-off-by: Anton Vorontsov --- drivers/power/lp8727_charger.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/power/lp8727_charger.c b/drivers/power/lp8727_charger.c index b15b575c070c..c53dd1292f81 100644 --- a/drivers/power/lp8727_charger.c +++ b/drivers/power/lp8727_charger.c @@ -464,6 +464,7 @@ static int __devexit lp8727_remove(struct i2c_client *cl) static const struct i2c_device_id lp8727_ids[] = { {"lp8727", 0}, + { } }; static struct i2c_driver lp8727_driver = { -- cgit v1.2.3-59-g8ed1b From 8dc6ae4d448758a30cf5fa822d6fe6f4e15a04c6 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 1 Feb 2012 18:11:40 +0100 Subject: pinctrl: restore pin naming Commit ca53c5f1ca5c936777caca46b7c716a40682ce83 ("pinctrl: conjure names for unnamed pins") made pins lose their identity and only get autogenerated names. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 8fe15cf15ac8..894cd5e103da 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -189,7 +189,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->pctldev = pctldev; /* Copy basic pin info */ - if (pindesc->name) { + if (name) { pindesc->name = name; } else { pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number); -- cgit v1.2.3-59-g8ed1b From 5b02aa1e6e7cf7d3bbf8027dc7e05e0eb2f1e828 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 1 Feb 2012 16:07:41 -0500 Subject: xen/bootup: During bootup suppress XENBUS: Unable to read cpu state When the initial domain starts, it prints (depending on the amount of CPUs) a slew of XENBUS: Unable to read cpu state XENBUS: Unable to read cpu state XENBUS: Unable to read cpu state XENBUS: Unable to read cpu state which provide no useful information - as the error is a valid issue - but not on the initial domain. The reason is that the XenStore is not accessible at that time (it is after all the first guest) so the CPU hotplug watch cannot parse "availability/cpu" attribute. Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/cpu_hotplug.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/xen/cpu_hotplug.c b/drivers/xen/cpu_hotplug.c index 14e2d995e958..4dcfced107f5 100644 --- a/drivers/xen/cpu_hotplug.c +++ b/drivers/xen/cpu_hotplug.c @@ -30,7 +30,8 @@ static int vcpu_online(unsigned int cpu) sprintf(dir, "cpu/%u", cpu); err = xenbus_scanf(XBT_NIL, dir, "availability", "%s", state); if (err != 1) { - printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); + if (!xen_initial_domain()) + printk(KERN_ERR "XENBUS: Unable to read cpu state\n"); return err; } -- cgit v1.2.3-59-g8ed1b From e4de866a834620ef974f5ba86d394a13d2f0cf66 Mon Sep 17 00:00:00 2001 From: Konrad Rzeszutek Wilk Date: Wed, 25 Jan 2012 16:00:00 -0500 Subject: xen/pci[front|back]: Use %d instead of %1x for displaying PCI devfn. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit .. as the rest of the kernel is using that format. Suggested-by: Марк Коренберг Signed-off-by: Konrad Rzeszutek Wilk --- drivers/pci/xen-pcifront.c | 10 +++++----- drivers/xen/xen-pciback/pci_stub.c | 8 ++++---- drivers/xen/xen-pciback/xenbus.c | 5 +++-- 3 files changed, 12 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c index 7cf3d2fcf56a..1620088a0e7e 100644 --- a/drivers/pci/xen-pcifront.c +++ b/drivers/pci/xen-pcifront.c @@ -189,7 +189,7 @@ static int pcifront_bus_read(struct pci_bus *bus, unsigned int devfn, if (verbose_request) dev_info(&pdev->xdev->dev, - "read dev=%04x:%02x:%02x.%01x - offset %x size %d\n", + "read dev=%04x:%02x:%02x.%d - offset %x size %d\n", pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size); @@ -228,7 +228,7 @@ static int pcifront_bus_write(struct pci_bus *bus, unsigned int devfn, if (verbose_request) dev_info(&pdev->xdev->dev, - "write dev=%04x:%02x:%02x.%01x - " + "write dev=%04x:%02x:%02x.%d - " "offset %x size %d val %x\n", pci_domain_nr(bus), bus->number, PCI_SLOT(devfn), PCI_FUNC(devfn), where, size, val); @@ -432,7 +432,7 @@ static int __devinit pcifront_scan_bus(struct pcifront_device *pdev, d = pci_scan_single_device(b, devfn); if (d) dev_info(&pdev->xdev->dev, "New device on " - "%04x:%02x:%02x.%02x found.\n", domain, bus, + "%04x:%02x:%02x.%d found.\n", domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); } @@ -1041,7 +1041,7 @@ static int pcifront_detach_devices(struct pcifront_device *pdev) pci_dev = pci_get_slot(pci_bus, PCI_DEVFN(slot, func)); if (!pci_dev) { dev_dbg(&pdev->xdev->dev, - "Cannot get PCI device %04x:%02x:%02x.%02x\n", + "Cannot get PCI device %04x:%02x:%02x.%d\n", domain, bus, slot, func); continue; } @@ -1049,7 +1049,7 @@ static int pcifront_detach_devices(struct pcifront_device *pdev) pci_dev_put(pci_dev); dev_dbg(&pdev->xdev->dev, - "PCI device %04x:%02x:%02x.%02x removed.\n", + "PCI device %04x:%02x:%02x.%d removed.\n", domain, bus, slot, func); } diff --git a/drivers/xen/xen-pciback/pci_stub.c b/drivers/xen/xen-pciback/pci_stub.c index 7944a17f5cbf..19834d1c7c36 100644 --- a/drivers/xen/xen-pciback/pci_stub.c +++ b/drivers/xen/xen-pciback/pci_stub.c @@ -884,7 +884,7 @@ static inline int str_to_quirk(const char *buf, int *domain, int *bus, int int err; err = - sscanf(buf, " %04x:%02x:%02x.%1x-%08x:%1x:%08x", domain, bus, slot, + sscanf(buf, " %04x:%02x:%02x.%d-%08x:%1x:%08x", domain, bus, slot, func, reg, size, mask); if (err == 7) return 0; @@ -904,7 +904,7 @@ static int pcistub_device_id_add(int domain, int bus, int slot, int func) pci_dev_id->bus = bus; pci_dev_id->devfn = PCI_DEVFN(slot, func); - pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%01x\n", + pr_debug(DRV_NAME ": wants to seize %04x:%02x:%02x.%d\n", domain, bus, slot, func); spin_lock_irqsave(&device_ids_lock, flags); @@ -934,7 +934,7 @@ static int pcistub_device_id_remove(int domain, int bus, int slot, int func) err = 0; - pr_debug(DRV_NAME ": removed %04x:%02x:%02x.%01x from " + pr_debug(DRV_NAME ": removed %04x:%02x:%02x.%d from " "seize list\n", domain, bus, slot, func); } } @@ -1029,7 +1029,7 @@ static ssize_t pcistub_slot_show(struct device_driver *drv, char *buf) break; count += scnprintf(buf + count, PAGE_SIZE - count, - "%04x:%02x:%02x.%01x\n", + "%04x:%02x:%02x.%d\n", pci_dev_id->domain, pci_dev_id->bus, PCI_SLOT(pci_dev_id->devfn), PCI_FUNC(pci_dev_id->devfn)); diff --git a/drivers/xen/xen-pciback/xenbus.c b/drivers/xen/xen-pciback/xenbus.c index d5dcf8d5d3d9..64b11f99eacc 100644 --- a/drivers/xen/xen-pciback/xenbus.c +++ b/drivers/xen/xen-pciback/xenbus.c @@ -206,6 +206,7 @@ static int xen_pcibk_publish_pci_dev(struct xen_pcibk_device *pdev, goto out; } + /* Note: The PV protocol uses %02x, don't change it */ err = xenbus_printf(XBT_NIL, pdev->xdev->nodename, str, "%04x:%02x:%02x.%02x", domain, bus, PCI_SLOT(devfn), PCI_FUNC(devfn)); @@ -229,7 +230,7 @@ static int xen_pcibk_export_device(struct xen_pcibk_device *pdev, err = -EINVAL; xenbus_dev_fatal(pdev->xdev, err, "Couldn't locate PCI device " - "(%04x:%02x:%02x.%01x)! " + "(%04x:%02x:%02x.%d)! " "perhaps already in-use?", domain, bus, slot, func); goto out; @@ -274,7 +275,7 @@ static int xen_pcibk_remove_device(struct xen_pcibk_device *pdev, if (!dev) { err = -EINVAL; dev_dbg(&pdev->xdev->dev, "Couldn't locate PCI device " - "(%04x:%02x:%02x.%01x)! not owned by this domain\n", + "(%04x:%02x:%02x.%d)! not owned by this domain\n", domain, bus, slot, func); goto out; } -- cgit v1.2.3-59-g8ed1b From a43a5ccdfa5bd5b2f00aa9b2321df268c2e5d6e2 Mon Sep 17 00:00:00 2001 From: Jan Beulich Date: Tue, 24 Jan 2012 13:52:42 +0000 Subject: xenbus_dev: add missing error check to watch handling So far only the watch path was checked to be zero terminated, while the watch token was merely assumed to be. Signed-off-by: Jan Beulich Signed-off-by: Konrad Rzeszutek Wilk --- drivers/xen/xenbus/xenbus_dev_frontend.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'drivers') diff --git a/drivers/xen/xenbus/xenbus_dev_frontend.c b/drivers/xen/xenbus/xenbus_dev_frontend.c index 527dc2a3b89f..89f76252a16f 100644 --- a/drivers/xen/xenbus/xenbus_dev_frontend.c +++ b/drivers/xen/xenbus/xenbus_dev_frontend.c @@ -369,6 +369,10 @@ static int xenbus_write_watch(unsigned msg_type, struct xenbus_file_priv *u) goto out; } token++; + if (memchr(token, 0, u->u.msg.len - (token - path)) == NULL) { + rc = -EILSEQ; + goto out; + } if (msg_type == XS_WATCH) { watch = alloc_watch_adapter(path, token); -- cgit v1.2.3-59-g8ed1b From 822bfa51ce44f2c63c300fdb76dc99c4d5a5ca9f Mon Sep 17 00:00:00 2001 From: Dan Carpenter Date: Mon, 6 Feb 2012 10:20:45 +0100 Subject: cdrom: use copy_to_user() without the underscores "nframes" comes from the user and "nframes * CD_FRAMESIZE_RAW" can wrap on 32 bit systems. That would have been ok if we used the same wrapped value for the copy, but we use a shifted value. We should just use the checked version of copy_to_user() because it's not going to make a difference to the speed. Cc: stable@vger.kernel.com Signed-off-by: Dan Carpenter Signed-off-by: Jens Axboe --- drivers/cdrom/cdrom.c | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 55eaf474d32c..8fefe59f52a7 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -2119,11 +2119,6 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, if (!nr) return -ENOMEM; - if (!access_ok(VERIFY_WRITE, ubuf, nframes * CD_FRAMESIZE_RAW)) { - ret = -EFAULT; - goto out; - } - cgc.data_direction = CGC_DATA_READ; while (nframes > 0) { if (nr > nframes) @@ -2132,7 +2127,7 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW); if (ret) break; - if (__copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) { + if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) { ret = -EFAULT; break; } @@ -2140,7 +2135,6 @@ static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf, nframes -= nr; lba += nr; } -out: kfree(cgc.buffer); return ret; } -- cgit v1.2.3-59-g8ed1b From 218d06d79468ca2e6abf3679eea12d7d93d251ef Mon Sep 17 00:00:00 2001 From: Shubhrajyoti Datta Date: Tue, 20 Dec 2011 11:45:08 +0530 Subject: i2c: tegra: Add devexit_p() for remove It was originally missed in the __devinit/__devexit annotations. Signed-off-by: Shubhrajyoti D Acked-by: Stephen Warren Acked-by: Ben Dooks Signed-off-by: Olof Johansson --- drivers/i2c/busses/i2c-tegra.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/i2c/busses/i2c-tegra.c b/drivers/i2c/busses/i2c-tegra.c index 6381604696d3..0ab4a9548745 100644 --- a/drivers/i2c/busses/i2c-tegra.c +++ b/drivers/i2c/busses/i2c-tegra.c @@ -755,7 +755,7 @@ MODULE_DEVICE_TABLE(of, tegra_i2c_of_match); static struct platform_driver tegra_i2c_driver = { .probe = tegra_i2c_probe, - .remove = tegra_i2c_remove, + .remove = __devexit_p(tegra_i2c_remove), #ifdef CONFIG_PM .suspend = tegra_i2c_suspend, .resume = tegra_i2c_resume, -- cgit v1.2.3-59-g8ed1b From 4e8670e26135d8fbfd5e084fddc1a8ed9f8eb4cb Mon Sep 17 00:00:00 2001 From: Asai Thambi S P Date: Tue, 7 Feb 2012 07:54:31 +0100 Subject: mtip32xx: removed the irrelevant argument of mtip_hw_submit_io() and the unused member of struct driver_data Removed the following: * irrelevant argument 'barrier' of mtip_hw_submit_io() * unused member 'eh_active' of struct driver_data Signed-off-by: Asai Thambi S P Signed-off-by: Sam Bradshaw Signed-off-by: Jens Axboe --- drivers/block/mtip32xx/mtip32xx.c | 11 +++++------ drivers/block/mtip32xx/mtip32xx.h | 5 ----- 2 files changed, 5 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/block/mtip32xx/mtip32xx.c b/drivers/block/mtip32xx/mtip32xx.c index b74eab70c3d0..8eb81c96608f 100644 --- a/drivers/block/mtip32xx/mtip32xx.c +++ b/drivers/block/mtip32xx/mtip32xx.c @@ -2068,8 +2068,6 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, * when the read completes. * @data Callback data passed to the callback function * when the read completes. - * @barrier If non-zero, this command must be completed before - * issuing any other commands. * @dir Direction (read or write) * * return value @@ -2077,7 +2075,7 @@ static int mtip_hw_ioctl(struct driver_data *dd, unsigned int cmd, */ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, int nsect, int nents, int tag, void *callback, - void *data, int barrier, int dir) + void *data, int dir) { struct host_to_dev_fis *fis; struct mtip_port *port = dd->port; @@ -2108,8 +2106,6 @@ static void mtip_hw_submit_io(struct driver_data *dd, sector_t start, *((unsigned int *) &fis->lba_low) = (start & 0xFFFFFF); *((unsigned int *) &fis->lba_low_ex) = ((start >> 24) & 0xFFFFFF); fis->device = 1 << 6; - if (barrier) - fis->device |= FUA_BIT; fis->features = nsect & 0xFF; fis->features_ex = (nsect >> 8) & 0xFF; fis->sect_count = ((tag << 3) | (tag >> 5)); @@ -3087,7 +3083,6 @@ static void mtip_make_request(struct request_queue *queue, struct bio *bio) tag, bio_endio, bio, - bio->bi_rw & REQ_FUA, bio_data_dir(bio)); } else bio_io_error(bio); @@ -3187,6 +3182,10 @@ skip_create_disk: blk_queue_max_segments(dd->queue, MTIP_MAX_SG); blk_queue_physical_block_size(dd->queue, 4096); blk_queue_io_min(dd->queue, 4096); + /* + * write back cache is not supported in the device. FUA depends on + * write back cache support, hence setting flush support to zero. + */ blk_queue_flush(dd->queue, 0); /* Set the capacity of the device in 512 byte sectors. */ diff --git a/drivers/block/mtip32xx/mtip32xx.h b/drivers/block/mtip32xx/mtip32xx.h index 723d7c4946dc..e0554a8f2233 100644 --- a/drivers/block/mtip32xx/mtip32xx.h +++ b/drivers/block/mtip32xx/mtip32xx.h @@ -104,9 +104,6 @@ /* BAR number used to access the HBA registers. */ #define MTIP_ABAR 5 -/* Forced Unit Access Bit */ -#define FUA_BIT 0x80 - #ifdef DEBUG #define dbg_printk(format, arg...) \ printk(pr_fmt(format), ##arg); @@ -415,8 +412,6 @@ struct driver_data { atomic_t resumeflag; /* Atomic variable to track suspend/resume */ - atomic_t eh_active; /* Flag for error handling tracking */ - struct task_struct *mtip_svc_handler; /* task_struct of svc thd */ }; -- cgit v1.2.3-59-g8ed1b From cdccaa9467b982d57b139818d15e1e994feca372 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 8 Feb 2012 20:03:14 +0100 Subject: cdrom: move shared static to cdrom_device_info The keeplocked variable in the cdrom driver is shared across multiple drives, but set in per-device ioctls. Move it to the per-device struct, avoiding that the setting on one drive affects the driver's behavior when closing another. [ Impact: limit udev's confusion to one drive when a CD burning program unlocks the CD door at the end of burning. ] Signed-off-by: Paolo Bonzini Signed-off-by: Jens Axboe --- drivers/cdrom/cdrom.c | 12 +++++------- include/linux/cdrom.h | 3 ++- 2 files changed, 7 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c index 8fefe59f52a7..d620b4495745 100644 --- a/drivers/cdrom/cdrom.c +++ b/drivers/cdrom/cdrom.c @@ -286,8 +286,6 @@ /* used to tell the module to turn on full debugging messages */ static bool debug; -/* used to keep tray locked at all times */ -static int keeplocked; /* default compatibility mode */ static bool autoclose=1; static bool autoeject; @@ -1204,7 +1202,7 @@ void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode) cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name); cdrom_dvd_rw_close_write(cdi); - if ((cdo->capability & CDC_LOCK) && !keeplocked) { + if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) { cdinfo(CD_CLOSE, "Unlocking door!\n"); cdo->lock_door(cdi, 0); } @@ -1371,7 +1369,7 @@ static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot) curslot = info->hdr.curslot; kfree(info); - if (cdi->use_count > 1 || keeplocked) { + if (cdi->use_count > 1 || cdi->keeplocked) { if (slot == CDSL_CURRENT) { return curslot; } else { @@ -2289,7 +2287,7 @@ static int cdrom_ioctl_eject(struct cdrom_device_info *cdi) if (!CDROM_CAN(CDC_OPEN_TRAY)) return -ENOSYS; - if (cdi->use_count != 1 || keeplocked) + if (cdi->use_count != 1 || cdi->keeplocked) return -EBUSY; if (CDROM_CAN(CDC_LOCK)) { int ret = cdi->ops->lock_door(cdi, 0); @@ -2316,7 +2314,7 @@ static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi, if (!CDROM_CAN(CDC_OPEN_TRAY)) return -ENOSYS; - if (keeplocked) + if (cdi->keeplocked) return -EBUSY; cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT); @@ -2447,7 +2445,7 @@ static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi, if (!CDROM_CAN(CDC_LOCK)) return -EDRIVE_CANT_DO_THIS; - keeplocked = arg ? 1 : 0; + cdi->keeplocked = arg ? 1 : 0; /* * Don't unlock the door on multiple opens by default, but allow diff --git a/include/linux/cdrom.h b/include/linux/cdrom.h index 35eae4b67503..7c48029dffe6 100644 --- a/include/linux/cdrom.h +++ b/include/linux/cdrom.h @@ -952,7 +952,8 @@ struct cdrom_device_info { char name[20]; /* name of the device type */ /* per-device flags */ __u8 sanyo_slot : 2; /* Sanyo 3 CD changer support */ - __u8 reserved : 6; /* not used yet */ + __u8 keeplocked : 1; /* CDROM_LOCKDOOR status */ + __u8 reserved : 5; /* not used yet */ int cdda_method; /* see flags */ __u8 last_sense; __u8 media_written; /* dirty flag, DVD+RW bookkeeping */ -- cgit v1.2.3-59-g8ed1b From 3f9a5aabd0a9fe0e0cd308506f48963d79169aa7 Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 8 Feb 2012 20:03:38 +0100 Subject: floppy: Cleanup disk->queue before caling put_disk() if add_disk() was never called add_disk() takes gendisk reference on request queue. If driver failed during initialization and never called add_disk() then that extra reference is not taken. That reference is put in put_disk(). floppy driver allocates the disk, allocates queue, sets disk->queue and then relizes that floppy controller is not present. It tries to tear down everything and tries to put a reference down in put_disk() which was never taken. In such error cases cleanup disk->queue before calling put_disk() so that we never try to put down a reference which was never taken in first place. Reported-and-tested-by: Suresh Jayaraman Tested-by: Dirk Gouders Signed-off-by: Vivek Goyal Acked-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/block/floppy.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 510fb10ec45a..401ba7833212 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4368,8 +4368,14 @@ out_unreg_blkdev: out_put_disk: while (dr--) { del_timer_sync(&motor_off_timer[dr]); - if (disks[dr]->queue) + if (disks[dr]->queue) { blk_cleanup_queue(disks[dr]->queue); + /* + * put_disk() is not paired with add_disk() and + * will put queue reference one extra time. fix it. + */ + disks[dr]->queue = NULL; + } put_disk(disks[dr]); } return err; -- cgit v1.2.3-59-g8ed1b From 4609dff6b5d11e1ed5ff935e15f9f6022acb312b Mon Sep 17 00:00:00 2001 From: Vivek Goyal Date: Wed, 8 Feb 2012 20:03:39 +0100 Subject: floppy: Fix a crash during rmmod floppy driver does not call add_disk() on all the drives hence we don't take gendisk reference on request queue for these drives. Don't call put_disk() with disk->queue set, otherwise we try to put the reference we never took. Reported-and-tested-by: Dirk Gouders Signed-off-by: Vivek Goyal Acked-by: Tejun Heo Signed-off-by: Jens Axboe --- drivers/block/floppy.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers') diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c index 401ba7833212..9baf11e86362 100644 --- a/drivers/block/floppy.c +++ b/drivers/block/floppy.c @@ -4585,6 +4585,15 @@ static void __exit floppy_module_exit(void) platform_device_unregister(&floppy_device[drive]); } blk_cleanup_queue(disks[drive]->queue); + + /* + * These disks have not called add_disk(). Don't put down + * queue reference in put_disk(). + */ + if (!(allowed_drive_mask & (1 << drive)) || + fdc_state[FDC(drive)].version == FDC_NONE) + disks[drive]->queue = NULL; + put_disk(disks[drive]); } -- cgit v1.2.3-59-g8ed1b From 306df0716aa285d378cc948fafed53c6ed895fe6 Mon Sep 17 00:00:00 2001 From: Dave Young Date: Wed, 8 Feb 2012 22:07:19 +0100 Subject: loop: zero fill bio instead of return -EIO for partial read commit 8268f5a741 ("deny partial write for loop dev fd") tried to fix the loop device partial read information leak problem. But it changed the semantics of read behavior. When we read beyond the end of the device we should get 0 bytes, which is normal behavior, we should not just return -EIO Instead of returning -EIO, zero out the bio to avoid information leak in case of partail read. Signed-off-by: Dave Young Reviewed-by: Jeff Moyer Tested-by: Jeff Moyer Cc: Dmitry Monakhov Signed-off-by: Andrew Morton Signed-off-by: Jens Axboe --- drivers/block/loop.c | 24 +++++++++++++----------- 1 file changed, 13 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/block/loop.c b/drivers/block/loop.c index f00257782fcc..cd504353b278 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -356,14 +356,14 @@ lo_direct_splice_actor(struct pipe_inode_info *pipe, struct splice_desc *sd) return __splice_from_pipe(pipe, sd, lo_splice_actor); } -static int +static ssize_t do_lo_receive(struct loop_device *lo, struct bio_vec *bvec, int bsize, loff_t pos) { struct lo_read_data cookie; struct splice_desc sd; struct file *file; - long retval; + ssize_t retval; cookie.lo = lo; cookie.page = bvec->bv_page; @@ -379,26 +379,28 @@ do_lo_receive(struct loop_device *lo, file = lo->lo_backing_file; retval = splice_direct_to_actor(file, &sd, lo_direct_splice_actor); - if (retval < 0) - return retval; - if (retval != bvec->bv_len) - return -EIO; - return 0; + return retval; } static int lo_receive(struct loop_device *lo, struct bio *bio, int bsize, loff_t pos) { struct bio_vec *bvec; - int i, ret = 0; + ssize_t s; + int i; bio_for_each_segment(bvec, bio, i) { - ret = do_lo_receive(lo, bvec, bsize, pos); - if (ret < 0) + s = do_lo_receive(lo, bvec, bsize, pos); + if (s < 0) + return s; + + if (s != bvec->bv_len) { + zero_fill_bio(bio); break; + } pos += bvec->bv_len; } - return ret; + return 0; } static int do_bio_filebacked(struct loop_device *lo, struct bio *bio) -- cgit v1.2.3-59-g8ed1b From 40410715715178ec196314dd0c19150c06901f80 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Feb 2012 09:44:55 +0000 Subject: ARM: omap: fix oops in drivers/video/omap2/dss/dpi.c When a PMIC is not found, this driver is unable to obtain its 'vdds_dsi_reg' regulator. Even through its initialization function fails, other code still calls its enable function, which fails to check whether it has this regulator before asking for it to be enabled. This fixes the oops, however a better fix would be to sort out the upper layers to prevent them calling into a module which failed to initialize. Unable to handle kernel NULL pointer dereference at virtual address 00000038 pgd = c0004000 [00000038] *pgd=00000000 Internal error: Oops: 5 [#1] PREEMPT Modules linked in: CPU: 0 Not tainted (3.3.0-rc2+ #228) PC is at regulator_enable+0x10/0x70 LR is at omapdss_dpi_display_enable+0x54/0x15c pc : [] lr : [] psr: 60000013 sp : c181fd90 ip : c181fdb0 fp : c181fdac r10: c042eff0 r9 : 00000060 r8 : c044a164 r7 : c042c0e4 r6 : c042bd60 r5 : 00000000 r4 : c042bd60 r3 : c084de48 r2 : c181e000 r1 : c042bd60 r0 : 00000000 Flags: nZCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 80004019 DAC: 00000015 Process swapper (pid: 1, stack limit = 0xc181e2e8) Stack: (0xc181fd90 to 0xc1820000) fd80: c001754c c042bd60 00000000 c042bd60 fda0: c181fdcc c181fdb0 c01af994 c01b9a04 c0016104 c042bd60 c042bd60 c044a338 fdc0: c181fdec c181fdd0 c01b5ed0 c01af94c c042bd60 c042bd60 c1aa8000 c1aa8a0c fde0: c181fe04 c181fdf0 c01b5f54 c01b5ea8 c02fc18c c042bd60 c181fe3c c181fe08 fe00: c01b2a18 c01b5f48 c01aed14 c02fc160 c01df8ec 00000002 c042bd60 00000003 fe20: c042bd60 c1aa8000 c1aa8a0c c042eff8 c181fe84 c181fe40 c01b3874 c01b29fc fe40: c042eff8 00000000 c042f000 c0449db8 c044ed78 00000000 c181fe74 c042eff8 fe60: c042eff8 c0449db8 c0449db8 c044ed78 00000000 00000000 c181fe94 c181fe88 fe80: c01e452c c01b35e8 c181feb4 c181fe98 c01e2fdc c01e4518 c042eff8 c0449db8 fea0: c0449db8 c181fef0 c181fecc c181feb8 c01e3104 c01e2f48 c042eff8 c042f02c fec0: c181feec c181fed0 c01e3190 c01e30c0 c01e311c 00000000 c01e311c c0449db8 fee0: c181ff14 c181fef0 c01e1998 c01e3128 c18330a8 c1892290 c04165e8 c0449db8 ff00: c0449db8 c1ab60c0 c181ff24 c181ff18 c01e2e28 c01e194c c181ff54 c181ff28 ff20: c01e2218 c01e2e14 c039afed c181ff38 c04165e8 c041660c c0449db8 00000013 ff40: 00000000 c03ffdb8 c181ff7c c181ff58 c01e384c c01e217c c181ff7c c04165e8 ff60: c041660c c003a37c 00000013 00000000 c181ff8c c181ff80 c01e488c c01e3790 ff80: c181ff9c c181ff90 c03ffdcc c01e484c c181ffdc c181ffa0 c0008798 c03ffdc4 ffa0: c181ffc4 c181ffb0 c0056440 c0187810 c003a37c c04165e8 c041660c c003a37c ffc0: 00000013 00000000 00000000 00000000 c181fff4 c181ffe0 c03ea284 c0008708 ffe0: 00000000 c03ea208 00000000 c181fff8 c003a37c c03ea214 1073cec0 01f7ee08 Backtrace: [] (regulator_enable+0x0/0x70) from [] (omapdss_dpi_display_enable+0x54/0x15c) r6:c042bd60 r5:00000000 r4:c042bd60 [] (omapdss_dpi_display_enable+0x0/0x15c) from [] (generic_dpi_panel_power_on+0x34/0x78) r6:c044a338 r5:c042bd60 r4:c042bd60 [] (generic_dpi_panel_power_on+0x0/0x78) from [] (generic_dpi_panel_enable+0x18/0x28) r7:c1aa8a0c r6:c1aa8000 r5:c042bd60 r4:c042bd60 [] (generic_dpi_panel_enable+0x0/0x28) from [] (omapfb_init_display+0x28/0x150) r4:c042bd60 [] (omapfb_init_display+0x0/0x150) from [] (omapfb_probe+0x298/0x318) r8:c042eff8 r7:c1aa8a0c r6:c1aa8000 r5:c042bd60 r4:00000003 [] (omapfb_probe+0x0/0x318) from [] (platform_drv_probe+0x20/0x24) [] (platform_drv_probe+0x0/0x24) from [] (really_probe+0xa0/0x178) [] (really_probe+0x0/0x178) from [] (driver_probe_device+0x50/0x68) r7:c181fef0 r6:c0449db8 r5:c0449db8 r4:c042eff8 [] (driver_probe_device+0x0/0x68) from [] (__driver_attach+0x74/0x98) r5:c042f02c r4:c042eff8 [] (__driver_attach+0x0/0x98) from [] (bus_for_each_dev+0x58/0x98) r6:c0449db8 r5:c01e311c r4:00000000 [] (bus_for_each_dev+0x0/0x98) from [] (driver_attach+0x20/0x28) r7:c1ab60c0 r6:c0449db8 r5:c0449db8 r4:c04165e8 [] (driver_attach+0x0/0x28) from [] (bus_add_driver+0xa8/0x22c) [] (bus_add_driver+0x0/0x22c) from [] (driver_register+0xc8/0x154) [] (driver_register+0x0/0x154) from [] (platform_driver_register+0x4c/0x60) r8:00000000 r7:00000013 r6:c003a37c r5:c041660c r4:c04165e8 [] (platform_driver_register+0x0/0x60) from [] (omapfb_init+0x14/0x34) [] (omapfb_init+0x0/0x34) from [] (do_one_initcall+0x9c/0x164) [] (do_one_initcall+0x0/0x164) from [] (kernel_init+0x7c/0x120) [] (kernel_init+0x0/0x120) from [] (do_exit+0x0/0x2d8) r5:c03ea208 r4:00000000 Code: e1a0c00d e92dd870 e24cb004 e24dd004 (e5906038) ---[ end trace 9e2474c2e193b223 ]--- Acked-by: Tony Lindgren Signed-off-by: Russell King --- drivers/video/omap2/dss/dpi.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 395d658a94fc..faaf305fda27 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -180,6 +180,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) { int r; + if (cpu_is_omap34xx() && !dpi.vdds_dsi_reg) { + DSSERR("no VDSS_DSI regulator\n"); + return -ENODEV; + } + if (dssdev->manager == NULL) { DSSERR("failed to enable display: no manager\n"); return -ENODEV; -- cgit v1.2.3-59-g8ed1b From 6252547b8a7acced581b649af4ebf6d65f63a34b Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Feb 2012 09:47:21 +0000 Subject: ARM: omap: fix broken twl-core dependencies and ifdefs In commit aeb5032b3f, a dependency on IRQ_DOMAIN was added, which causes regressions on previously working setups: a previously working non-DT kernel configuration now loses its PMIC support. The lack of PMIC support in turn causes the loss of other functionality the kernel had. This dependency was added because the driver now registers its interrupts with the IRQ domain code, presumably to prevent a build error. The result is that OMAP3 oopses in the vp.c code (fixed by a previous commit) due to the lack of PMIC support. However, even with IRQ_DOMAIN enabled, the driver oopses: Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 5 [#1] SMP Modules linked in: CPU: 1 Not tainted (3.3.0-rc2+ #271) PC is at irq_domain_add+0x1c/0x134 LR is at twl_probe+0xd0/0x370 pc : [] lr : [] psr: 00000113 sp : df843c48 ip : df843c68 fp : df843c64 r10: c02b93e4 r9 : 00000000 r8 : c029b9dc r7 : df9d8a00 r6 : c03bef90 r5 : 00000000 r4 : c03f5240 r3 : 00000000 r2 : c03f5240 r1 : 00000015 r0 : c03f5240 Flags: nzcv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel Control: 10c5387d Table: 8000404a DAC: 00000015 Process swapper/0 (pid: 1, stack limit = 0xdf8422f0) Stack: (0xdf843c48 to 0xdf844000) 3c40: 00000014 00000170 00000014 c03bef90 df843c9c df843c68 3c60: c029baac c007bac0 00000000 df9d8a20 00000001 c03cd238 c02b93e4 df9d8a20 3c80: df9d8a04 df9d8a00 c029b9dc df8cae08 df843cc4 df843ca0 c01eee70 c029b9e8 ... Backtrace: [] (irq_domain_add+0x0/0x134) from [] (twl_probe+0xd0/0x370) r6:c03bef90 r5:00000014 r4:00000170 [] (twl_probe+0x0/0x370) from [] (i2c_device_probe+0xb0/0xe4) [] (i2c_device_probe+0x0/0xe4) from [] (really_probe+0xa0/0x178) r8:df8f0070 r7:c03cd238 r6:df9d8a20 r5:df9d8a20 r4:df9d8a20 [] (really_probe+0x0/0x178) from [] (driver_probe_device+0x50/0x68) r7:df843d18 r6:df9d8a20 r5:c03cd238 r4:df9d8a20 [] (driver_probe_device+0x0/0x68) from [] (__device_attach+0x44/0x48) r5:df9d8a20 r4:c03cd238 [] (__device_attach+0x0/0x48) from [] (bus_for_each_drv+0x58/0x98) r5:c01d2104 r4:00000000 [] (bus_for_each_drv+0x0/0x98) from [] (device_attach+0x80/0xac) r7:df9d8a28 r6:df9d8a54 r5:c03cd978 r4:df9d8a20 [] (device_attach+0x0/0xac) from [] (bus_probe_device+0x34/0xa4) r6:df9d8a20 r5:c03cd978 r4:df9d8a20 [] (bus_probe_device+0x0/0xa4) from [] (device_add+0x2a0/0x420) r6:00000000 r5:df9d8a20 r4:df9d8a20 [] (device_add+0x0/0x420) from [] (device_register+0x20/0x24) r8:df9d8a00 r7:df9d8a04 r6:df8f0048 r5:df9d8a00 r4:df9d8a20 [] (device_register+0x0/0x24) from [] (i2c_new_device+0x118/0x180) r4:df9d8a20 [] (i2c_new_device+0x0/0x180) from [] (i2c_register_adapter+0x140/0x204) r8:c03cd970 r7:00000000 r6:df8f0070 r5:df8a6300 r4:df8f0048 [] (i2c_register_adapter+0x0/0x204) from [] (i2c_add_numbered_adapter+0xb4/0xcc) r8:df8a4c54 r7:df8cae00 r6:df843e2c r5:df8f0048 r4:00000000 [] (i2c_add_numbered_adapter+0x0/0xcc) from [] (omap_i2c_probe+0x2f8/0x3b4) r6:00000000 r5:df8f0000 r4:df8f0070 [] (omap_i2c_probe+0x0/0x3b4) from [] (platform_drv_probe+0x20/0x24) [] (platform_drv_probe+0x0/0x24) from [] (really_probe+0xa0/0x178) [] (really_probe+0x0/0x178) from [] (driver_probe_device+0x50/0x68) r7:df843ef0 r6:c03cdb2c r5:c03cdb2c r4:df8cae08 [] (driver_probe_device+0x0/0x68) from [] (__driver_attach+0x6c/0x90) r5:df8cae3c r4:df8cae08 [] (__driver_attach+0x0/0x90) from [] (bus_for_each_dev+0x58/0x98) r6:c03cdb2c r5:c01d2074 r4:00000000 [] (bus_for_each_dev+0x0/0x98) from [] (driver_attach+0x20/0x28) r7:df880b80 r6:c03cdb2c r5:c03cdb2c r4:c0394f28 [] (driver_attach+0x0/0x28) from [] (bus_add_driver+0xb4/0x230) [] (bus_add_driver+0x0/0x230) from [] (driver_register+0xc8/0x154) [] (driver_register+0x0/0x154) from [] (platform_driver_register+0x4c/0x60) r8:00000000 r7:00000013 r6:c00384c8 r5:c0395180 r4:c0394f28 [] (platform_driver_register+0x0/0x60) from [] (omap_i2c_init_driver+0x14/0x1c) [] (omap_i2c_init_driver+0x0/0x1c) from [] (do_one_initcall+0x9c/0x164) [] (do_one_initcall+0x0/0x164) from [] (kernel_init+0x90/0x138) [] (kernel_init+0x0/0x138) from [] (do_exit+0x0/0x2ec) r5:c036c264 r4:00000000 <0>Code: e24dd004 e5903014 e1a04000 e5905010 (e5933000) <4>---[ end trace 1b75b31a2719ed1c ]--- This happens because we try to register an IRQ domain with a NULL ops structure, and the first thing irq_domain_add() does is try to dereference this ops structure. So, fix the problem by getting rid of the incorrect OF_IRQ ifdef and wrapping the IRQ domain bits of the driver with an IRQ_DOMAIN ifdef instead. Acked-by: Tony Lindgren Signed-off-by: Russell King --- drivers/mfd/Kconfig | 2 +- drivers/mfd/twl-core.c | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index cd13e9f2f5e6..f147395bac9a 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -200,7 +200,7 @@ config MENELAUS config TWL4030_CORE bool "Texas Instruments TWL4030/TWL5030/TWL6030/TPS659x0 Support" - depends on I2C=y && GENERIC_HARDIRQS && IRQ_DOMAIN + depends on I2C=y && GENERIC_HARDIRQS help Say yes here if you have TWL4030 / TWL6030 family chip on your board. This core driver provides register access and IRQ handling diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index e04e04ddc15e..8ce3959c6919 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -263,7 +263,9 @@ struct twl_client { static struct twl_client twl_modules[TWL_NUM_SLAVES]; +#ifdef CONFIG_IRQ_DOMAIN static struct irq_domain domain; +#endif /* mapping the module id to slave id and base address */ struct twl_mapping { @@ -1226,13 +1228,13 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) pdata->irq_base = status; pdata->irq_end = pdata->irq_base + nr_irqs; +#ifdef CONFIG_IRQ_DOMAIN domain.irq_base = pdata->irq_base; domain.nr_irq = nr_irqs; -#ifdef CONFIG_OF_IRQ domain.of_node = of_node_get(node); domain.ops = &irq_domain_simple_ops; -#endif irq_domain_add(&domain); +#endif if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { dev_dbg(&client->dev, "can't talk I2C?\n"); -- cgit v1.2.3-59-g8ed1b From c27111e5b8d6b1e9296f7075cdc35872f672b524 Mon Sep 17 00:00:00 2001 From: Simon Graham Date: Thu, 9 Feb 2012 09:55:13 -0500 Subject: rtlwifi: Modify rtl_pci_init to return 0 on success Fixes problem where caller would think routine succeeded when it failed leading to divide by zero panic. Signed-off-by: Simon Graham Acked-by: Larry Finger Signed-off-by: John W. Linville --- drivers/net/wireless/rtlwifi/pci.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 39e0907a3c4e..9245d882c06a 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c @@ -1501,7 +1501,7 @@ static int rtl_pci_init(struct ieee80211_hw *hw, struct pci_dev *pdev) return err; } - return 1; + return 0; } static int rtl_pci_start(struct ieee80211_hw *hw) @@ -1870,7 +1870,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, } /* Init PCI sw */ - err = !rtl_pci_init(hw, pdev); + err = rtl_pci_init(hw, pdev); if (err) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, ("Failed to init PCI.\n")); -- cgit v1.2.3-59-g8ed1b From 532691635475487b8c1d6fc618bd123084904897 Mon Sep 17 00:00:00 2001 From: David Miller Date: Thu, 9 Feb 2012 16:43:01 -0500 Subject: regulator: Fix mc13xxx regulator modular build (again) Since mc13xxx-regulator-core.c and the actual drivers can get built into seperate modules, you have to export the DT support symbols "mc13xxx_get_num_regulators_dt" and "mc13xxx_parse_regulators_dt" otherwise the allmodconfig build fails on sparc64. [Updated the subject; the same thing was previously reported and fixed in -next but for some reason nobody noticed for some considerable time after the issue was introduced -- broonie] Signed-off-by: David S. Miller Signed-off-by: Mark Brown --- drivers/regulator/mc13xxx-regulator-core.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'drivers') diff --git a/drivers/regulator/mc13xxx-regulator-core.c b/drivers/regulator/mc13xxx-regulator-core.c index 80ecafef1bc3..62dcd0a432bb 100644 --- a/drivers/regulator/mc13xxx-regulator-core.c +++ b/drivers/regulator/mc13xxx-regulator-core.c @@ -254,6 +254,7 @@ int __devinit mc13xxx_get_num_regulators_dt(struct platform_device *pdev) return num; } +EXPORT_SYMBOL_GPL(mc13xxx_get_num_regulators_dt); struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( struct platform_device *pdev, struct mc13xxx_regulator *regulators, @@ -291,6 +292,7 @@ struct mc13xxx_regulator_init_data * __devinit mc13xxx_parse_regulators_dt( return data; } +EXPORT_SYMBOL_GPL(mc13xxx_parse_regulators_dt); #endif MODULE_LICENSE("GPL v2"); -- cgit v1.2.3-59-g8ed1b From 9fc886a1880766fb91cb27c2e96bd814cef640d6 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Tue, 7 Feb 2012 11:12:55 +0800 Subject: regulator: Fix getting voltage in max8649_enable_time() Current code takes wrong parameter while calling max8649_list_voltage. Signed-off-by: Axel Lin Signed-off-by: Mark Brown --- drivers/regulator/max8649.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/regulator/max8649.c b/drivers/regulator/max8649.c index b06a2399587c..d0e1180ad961 100644 --- a/drivers/regulator/max8649.c +++ b/drivers/regulator/max8649.c @@ -150,7 +150,7 @@ static int max8649_enable_time(struct regulator_dev *rdev) if (ret != 0) return ret; val &= MAX8649_VOL_MASK; - voltage = max8649_list_voltage(rdev, (unsigned char)ret); /* uV */ + voltage = max8649_list_voltage(rdev, (unsigned char)val); /* uV */ /* get rate */ ret = regmap_read(info->regmap, MAX8649_RAMP, &val); -- cgit v1.2.3-59-g8ed1b From 71f6bd4a23130cd2f4b036010c5790b1295290b9 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Mon, 30 Jan 2012 12:25:24 +0100 Subject: PCI: workaround hard-wired bus number V2 Fixes PCI device detection on IBM xSeries IBM 3850 M2 / x3950 M2 when using ACPI resources (_CRS). This is default, a manual workaround (without this patch) would be pci=nocrs boot param. V2: Add dev_warn if the workaround is hit. This should reveal how common such setups are (via google) and point to possible problems if things are still not working as expected. -> Suggested by Jan Beulich. Cc: stable@vger.kernel.org Tested-by: garyhade@us.ibm.com Signed-off-by: Yinghai Lu Signed-off-by: Jesse Barnes --- drivers/pci/probe.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c index 7cc9e2f0f47c..71eac9cd724d 100644 --- a/drivers/pci/probe.c +++ b/drivers/pci/probe.c @@ -651,6 +651,11 @@ int __devinit pci_scan_bridge(struct pci_bus *bus, struct pci_dev *dev, int max, dev_dbg(&dev->dev, "scanning [bus %02x-%02x] behind bridge, pass %d\n", secondary, subordinate, pass); + if (!primary && (primary != bus->number) && secondary && subordinate) { + dev_warn(&dev->dev, "Primary bus is hard wired to 0\n"); + primary = bus->number; + } + /* Check if setup is sensible at all */ if (!pass && (primary != bus->number || secondary <= bus->number)) { -- cgit v1.2.3-59-g8ed1b From 8161fe91d8da34c1a231b6e2d4454b4b3179a5d4 Mon Sep 17 00:00:00 2001 From: Vaidyanathan Srinivasan Date: Thu, 2 Feb 2012 23:11:20 +0530 Subject: PCI: set pci sriov page size before reading SRIOV BAR For an SRIOV device, PCI_SRIOV_SYS_PGSIZE should be set before the PCI_SRIOV_BAR are queried. The sys pagesize defaults to 4k, so this change is required on powerpc box with 64k base page size. This is a regression caused due to moving SRIOV init to sriov_enable(). | commit afd24ece5c76af87f6fc477f2747b83a764f161c | Author: Ram Pai | PCI: delay configuration of SRIOV capability | The SRIOV capability, namely page size and total_vfs of a device are | configured during enumeration phase of the device. This can potentially | interfere with the PCI operations of the platform, if the IOV capability | of the device is not enabled. Signed-off-by: Vaidyanathan Srinivasan Acked-by: Ram Pai Signed-off-by: Jesse Barnes --- drivers/pci/iov.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/iov.c b/drivers/pci/iov.c index 0321fa3b4226..0dab5ecf61bb 100644 --- a/drivers/pci/iov.c +++ b/drivers/pci/iov.c @@ -347,8 +347,6 @@ static int sriov_enable(struct pci_dev *dev, int nr_virtfn) return rc; } - pci_write_config_dword(dev, iov->pos + PCI_SRIOV_SYS_PGSIZE, iov->pgsz); - iov->ctrl |= PCI_SRIOV_CTRL_VFE | PCI_SRIOV_CTRL_MSE; pci_cfg_access_lock(dev); pci_write_config_word(dev, iov->pos + PCI_SRIOV_CTRL, iov->ctrl); @@ -466,6 +464,7 @@ found: return -EIO; pgsz &= ~(pgsz - 1); + pci_write_config_dword(dev, pos + PCI_SRIOV_SYS_PGSIZE, pgsz); nres = 0; for (i = 0; i < PCI_SRIOV_NUM_BARS; i++) { -- cgit v1.2.3-59-g8ed1b From 3682a3946d2b0bad621db871e3bead83e523a238 Mon Sep 17 00:00:00 2001 From: Yinghai Lu Date: Sat, 4 Feb 2012 22:55:00 -0800 Subject: PCI: Fix pci cardbus removal During test busn_res allocation with cardbus, found pci card removal is not working anymore, and it turns out it is broken by: |commit 79cc9601c3e42b4f0650fe7e69132ebce7ab48f9 |Date: Tue Nov 22 21:06:53 2011 -0800 | | PCI: Only call pci_stop_bus_device() one time for child devices at remove The above changed the behavior of pci_remove_behind_bridge that yenta_cardbus depended on. So restore the old behavoir of pci_remove_behind_bridge (which requires stopping and removing of all devices) by: 1. rename pci_remove_behind_bridge to __pci_remove_behind_bridge, and let __pci_remove_bus_device() call it instead. 2. add pci_stop_behind_bridge that will stop devices behind a bridge 3. add back pci_remove_behind_bridge that will stop and remove devices under bridge. -v2: update commit description a little bit. Tested-by: Dominik Brodowski Signed-off-by: Yinghai Lu Signed-off-by: Jesse Barnes --- drivers/pci/remove.c | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 6def3624c688..ef8b18c48f26 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -77,6 +77,7 @@ void pci_remove_bus(struct pci_bus *pci_bus) } EXPORT_SYMBOL(pci_remove_bus); +static void __pci_remove_behind_bridge(struct pci_dev *dev); /** * pci_remove_bus_device - remove a PCI device and any children * @dev: the device to remove @@ -94,7 +95,7 @@ static void __pci_remove_bus_device(struct pci_dev *dev) if (dev->subordinate) { struct pci_bus *b = dev->subordinate; - pci_remove_behind_bridge(dev); + __pci_remove_behind_bridge(dev); pci_remove_bus(b); dev->subordinate = NULL; } @@ -107,6 +108,24 @@ void pci_remove_bus_device(struct pci_dev *dev) __pci_remove_bus_device(dev); } +static void __pci_remove_behind_bridge(struct pci_dev *dev) +{ + struct list_head *l, *n; + + if (dev->subordinate) + list_for_each_safe(l, n, &dev->subordinate->devices) + __pci_remove_bus_device(pci_dev_b(l)); +} + +static void pci_stop_behind_bridge(struct pci_dev *dev) +{ + struct list_head *l, *n; + + if (dev->subordinate) + list_for_each_safe(l, n, &dev->subordinate->devices) + pci_stop_bus_device(pci_dev_b(l)); +} + /** * pci_remove_behind_bridge - remove all devices behind a PCI bridge * @dev: PCI bridge device @@ -117,11 +136,8 @@ void pci_remove_bus_device(struct pci_dev *dev) */ void pci_remove_behind_bridge(struct pci_dev *dev) { - struct list_head *l, *n; - - if (dev->subordinate) - list_for_each_safe(l, n, &dev->subordinate->devices) - __pci_remove_bus_device(pci_dev_b(l)); + pci_stop_behind_bridge(dev); + __pci_remove_behind_bridge(dev); } static void pci_stop_bus_devices(struct pci_bus *bus) -- cgit v1.2.3-59-g8ed1b From ba8c4dc99808b1de809a0eda71a32f26efdafd92 Mon Sep 17 00:00:00 2001 From: Roy Zang Date: Fri, 13 Jan 2012 15:02:01 +0800 Subject: mmc: esdhc: fix errors when booting kernel on Freescale eSDHC version 2.3 When eSDHC module is enabled on P5020/P3041/P2041/P1010 with eSDHC version 2.3, there is following errors: mmc0: Timeout waiting for hardware interrupt. mmc0: error -110 whilst initialising SD card mmc0: Unexpected interrupt 0x02000000. mmc0: Timeout waiting for hardware interrupt. mmc0: error -110 whilst initialising SD card mmc0: Unexpected interrupt 0x02000000. It is because eSDHC controller has different bit setting for PROCTL register at 0x28 comparing SD specification. This patch sets DMAS bits correctly for byte operation and does not change the default value of other field of PROCTL register. For other FSL chips, such as MPC8536/P2020, PROCTL[DMAS] bits are reserved and even if they are set to wrong bits, it will not take effective. Signed-off-by: Roy Zang Acked-by: Anton Vorontsov Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-of-esdhc.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-of-esdhc.c b/drivers/mmc/host/sdhci-of-esdhc.c index ff4adc018041..5d876ff86f37 100644 --- a/drivers/mmc/host/sdhci-of-esdhc.c +++ b/drivers/mmc/host/sdhci-of-esdhc.c @@ -38,6 +38,23 @@ static u8 esdhc_readb(struct sdhci_host *host, int reg) int base = reg & ~0x3; int shift = (reg & 0x3) * 8; u8 ret = (in_be32(host->ioaddr + base) >> shift) & 0xff; + + /* + * "DMA select" locates at offset 0x28 in SD specification, but on + * P5020 or P3041, it locates at 0x29. + */ + if (reg == SDHCI_HOST_CONTROL) { + u32 dma_bits; + + dma_bits = in_be32(host->ioaddr + reg); + /* DMA select is 22,23 bits in Protocol Control Register */ + dma_bits = (dma_bits >> 5) & SDHCI_CTRL_DMA_MASK; + + /* fixup the result */ + ret &= ~SDHCI_CTRL_DMA_MASK; + ret |= dma_bits; + } + return ret; } @@ -56,6 +73,21 @@ static void esdhc_writew(struct sdhci_host *host, u16 val, int reg) static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg) { + /* + * "DMA select" location is offset 0x28 in SD specification, but on + * P5020 or P3041, it's located at 0x29. + */ + if (reg == SDHCI_HOST_CONTROL) { + u32 dma_bits; + + /* DMA select is 22,23 bits in Protocol Control Register */ + dma_bits = (val & SDHCI_CTRL_DMA_MASK) << 5; + clrsetbits_be32(host->ioaddr + reg , SDHCI_CTRL_DMA_MASK << 5, + dma_bits); + val &= ~SDHCI_CTRL_DMA_MASK; + val |= in_be32(host->ioaddr + reg) & SDHCI_CTRL_DMA_MASK; + } + /* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */ if (reg == SDHCI_HOST_CONTROL) val &= ~ESDHC_HOST_CONTROL_RES; -- cgit v1.2.3-59-g8ed1b From a0bb10e86642064f6cec9e23f523127e5cfbe609 Mon Sep 17 00:00:00 2001 From: Russell King Date: Tue, 7 Feb 2012 10:00:34 +0000 Subject: ARM: omap: fix section mismatch errors in TWL PMIC driver WARNING: drivers/mfd/built-in.o(.devinit.text+0x258): Section mismatch in reference from the function twl_probe() to the function .init.text:twl4030_power_init() The function __devinit twl_probe() references a function __init twl4030_power_init(). If twl4030_power_init is only used by twl_probe then annotate twl4030_power_init with a matching annotation. twl4030_power_init() references other __init marked functions, so these too must become __devinit. Acked-by: Tony Lindgren Signed-off-by: Russell King --- drivers/mfd/twl4030-power.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/mfd/twl4030-power.c b/drivers/mfd/twl4030-power.c index d905f5171153..79ca33dfacca 100644 --- a/drivers/mfd/twl4030-power.c +++ b/drivers/mfd/twl4030-power.c @@ -124,7 +124,7 @@ static u8 res_config_addrs[] = { [RES_MAIN_REF] = 0x94, }; -static int __init twl4030_write_script_byte(u8 address, u8 byte) +static int __devinit twl4030_write_script_byte(u8 address, u8 byte) { int err; @@ -138,7 +138,7 @@ out: return err; } -static int __init twl4030_write_script_ins(u8 address, u16 pmb_message, +static int __devinit twl4030_write_script_ins(u8 address, u16 pmb_message, u8 delay, u8 next) { int err; @@ -158,7 +158,7 @@ out: return err; } -static int __init twl4030_write_script(u8 address, struct twl4030_ins *script, +static int __devinit twl4030_write_script(u8 address, struct twl4030_ins *script, int len) { int err; @@ -183,7 +183,7 @@ static int __init twl4030_write_script(u8 address, struct twl4030_ins *script, return err; } -static int __init twl4030_config_wakeup3_sequence(u8 address) +static int __devinit twl4030_config_wakeup3_sequence(u8 address) { int err; u8 data; @@ -208,7 +208,7 @@ out: return err; } -static int __init twl4030_config_wakeup12_sequence(u8 address) +static int __devinit twl4030_config_wakeup12_sequence(u8 address) { int err = 0; u8 data; @@ -262,7 +262,7 @@ out: return err; } -static int __init twl4030_config_sleep_sequence(u8 address) +static int __devinit twl4030_config_sleep_sequence(u8 address) { int err; @@ -276,7 +276,7 @@ static int __init twl4030_config_sleep_sequence(u8 address) return err; } -static int __init twl4030_config_warmreset_sequence(u8 address) +static int __devinit twl4030_config_warmreset_sequence(u8 address) { int err; u8 rd_data; @@ -324,7 +324,7 @@ out: return err; } -static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig) +static int __devinit twl4030_configure_resource(struct twl4030_resconfig *rconfig) { int rconfig_addr; int err; @@ -416,7 +416,7 @@ static int __init twl4030_configure_resource(struct twl4030_resconfig *rconfig) return 0; } -static int __init load_twl4030_script(struct twl4030_script *tscript, +static int __devinit load_twl4030_script(struct twl4030_script *tscript, u8 address) { int err; @@ -527,7 +527,7 @@ void twl4030_power_off(void) pr_err("TWL4030 Unable to power off\n"); } -void __init twl4030_power_init(struct twl4030_power_data *twl4030_scripts) +void __devinit twl4030_power_init(struct twl4030_power_data *twl4030_scripts) { int err = 0; int i; -- cgit v1.2.3-59-g8ed1b From 2dcc90e6ac06d78433aec682961d9b587a07d4b5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 18 Sep 2011 10:17:54 +0800 Subject: ARM: at91:rtc/rtc-at91sam9: ioremap register bank Instead of computing virtual address with AT91_VA_BASE_SYS, use the appropriate ioremap() call on the driver "memory" resource. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- drivers/rtc/rtc-at91sam9.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/rtc/rtc-at91sam9.c b/drivers/rtc/rtc-at91sam9.c index a3ad957507dc..ee3c122c0599 100644 --- a/drivers/rtc/rtc-at91sam9.c +++ b/drivers/rtc/rtc-at91sam9.c @@ -307,8 +307,12 @@ static int __init at91_rtc_probe(struct platform_device *pdev) device_init_wakeup(&pdev->dev, 1); platform_set_drvdata(pdev, rtc); - rtc->rtt = (void __force __iomem *) (AT91_VA_BASE_SYS - AT91_BASE_SYS); - rtc->rtt += r->start; + rtc->rtt = ioremap(r->start, resource_size(r)); + if (!rtc->rtt) { + dev_err(&pdev->dev, "failed to map registers, aborting.\n"); + ret = -ENOMEM; + goto fail; + } mr = rtt_readl(rtc, MR); @@ -326,7 +330,7 @@ static int __init at91_rtc_probe(struct platform_device *pdev) &at91_rtc_ops, THIS_MODULE); if (IS_ERR(rtc->rtcdev)) { ret = PTR_ERR(rtc->rtcdev); - goto fail; + goto fail_register; } /* register irq handler after we know what name we'll use */ @@ -351,6 +355,8 @@ static int __init at91_rtc_probe(struct platform_device *pdev) return 0; +fail_register: + iounmap(rtc->rtt); fail: platform_set_drvdata(pdev, NULL); kfree(rtc); @@ -371,6 +377,7 @@ static int __exit at91_rtc_remove(struct platform_device *pdev) rtc_device_unregister(rtc->rtcdev); + iounmap(rtc->rtt); platform_set_drvdata(pdev, NULL); kfree(rtc); return 0; -- cgit v1.2.3-59-g8ed1b From 88dcde98ad113411f45ea7e8261839f7a1ba3c33 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Sun, 27 Nov 2011 19:30:29 +0800 Subject: pata/at91: use newly introduced SMC accessors pata_at91 driver is broken since faee0cc: "make smc register base soc independent" Fix it with newly introduced SMC accessors. The overall action of removal of at91_sys_read/write will allow to use the pata_at91 on a single zImage kernel. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre Cc: linux-ide@vger.kernel.org --- drivers/ata/pata_at91.c | 48 +++++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/ata/pata_at91.c b/drivers/ata/pata_at91.c index a7d91a72ee35..53d3770a0b1b 100644 --- a/drivers/ata/pata_at91.c +++ b/drivers/ata/pata_at91.c @@ -207,11 +207,11 @@ static void set_smc_timing(struct device *dev, struct ata_device *adev, { int ret = 0; int use_iordy; + struct sam9_smc_config smc; unsigned int t6z; /* data tristate time in ns */ unsigned int cycle; /* SMC Cycle width in MCK ticks */ unsigned int setup; /* SMC Setup width in MCK ticks */ unsigned int pulse; /* CFIOR and CFIOW pulse width in MCK ticks */ - unsigned int cs_setup = 0;/* CS4 or CS5 setup width in MCK ticks */ unsigned int cs_pulse; /* CS4 or CS5 pulse width in MCK ticks*/ unsigned int tdf_cycles; /* SMC TDF MCK ticks */ unsigned long mck_hz; /* MCK frequency in Hz */ @@ -244,26 +244,20 @@ static void set_smc_timing(struct device *dev, struct ata_device *adev, } dev_dbg(dev, "Use IORDY=%u, TDF Cycles=%u\n", use_iordy, tdf_cycles); - info->mode |= AT91_SMC_TDF_(tdf_cycles); - - /* write SMC Setup Register */ - at91_sys_write(AT91_SMC_SETUP(info->cs), - AT91_SMC_NWESETUP_(setup) | - AT91_SMC_NRDSETUP_(setup) | - AT91_SMC_NCS_WRSETUP_(cs_setup) | - AT91_SMC_NCS_RDSETUP_(cs_setup)); - /* write SMC Pulse Register */ - at91_sys_write(AT91_SMC_PULSE(info->cs), - AT91_SMC_NWEPULSE_(pulse) | - AT91_SMC_NRDPULSE_(pulse) | - AT91_SMC_NCS_WRPULSE_(cs_pulse) | - AT91_SMC_NCS_RDPULSE_(cs_pulse)); - /* write SMC Cycle Register */ - at91_sys_write(AT91_SMC_CYCLE(info->cs), - AT91_SMC_NWECYCLE_(cycle) | - AT91_SMC_NRDCYCLE_(cycle)); - /* write SMC Mode Register*/ - at91_sys_write(AT91_SMC_MODE(info->cs), info->mode); + + /* SMC Setup Register */ + smc.nwe_setup = smc.nrd_setup = setup; + smc.ncs_write_setup = smc.ncs_read_setup = 0; + /* SMC Pulse Register */ + smc.nwe_pulse = smc.nrd_pulse = pulse; + smc.ncs_write_pulse = smc.ncs_read_pulse = cs_pulse; + /* SMC Cycle Register */ + smc.write_cycle = smc.read_cycle = cycle; + /* SMC Mode Register*/ + smc.tdf_cycles = tdf_cycles; + smc.mode = info->mode; + + sam9_smc_configure(0, info->cs, &smc); } static void pata_at91_set_piomode(struct ata_port *ap, struct ata_device *adev) @@ -288,20 +282,20 @@ static unsigned int pata_at91_data_xfer_noirq(struct ata_device *dev, struct at91_ide_info *info = dev->link->ap->host->private_data; unsigned int consumed; unsigned long flags; - unsigned int mode; + struct sam9_smc_config smc; local_irq_save(flags); - mode = at91_sys_read(AT91_SMC_MODE(info->cs)); + sam9_smc_read_mode(0, info->cs, &smc); /* set 16bit mode before writing data */ - at91_sys_write(AT91_SMC_MODE(info->cs), - (mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_16); + smc.mode = (smc.mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_16; + sam9_smc_write_mode(0, info->cs, &smc); consumed = ata_sff_data_xfer(dev, buf, buflen, rw); /* restore 8bit mode after data is written */ - at91_sys_write(AT91_SMC_MODE(info->cs), - (mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_8); + smc.mode = (smc.mode & ~AT91_SMC_DBW) | AT91_SMC_DBW_8; + sam9_smc_write_mode(0, info->cs, &smc); local_irq_restore(flags); return consumed; -- cgit v1.2.3-59-g8ed1b From cf844751fb25e095d8fa30332cb173a73e5a736c Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Thu, 15 Dec 2011 21:24:03 +0800 Subject: ARM: at91: drop ide driver in favor of the pata one Driver at91_ide is broken and should not be fixed: remove it. Modification of device files that where making use of it. The PATA driver (pata_at91) is able to replace at91_ide. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Nicolas Ferre --- arch/arm/mach-at91/at91sam9260_devices.c | 7 +- arch/arm/mach-at91/at91sam9263_devices.c | 6 +- drivers/ide/Makefile | 1 - drivers/ide/at91_ide.c | 366 ------------------------------- 4 files changed, 5 insertions(+), 375 deletions(-) delete mode 100644 drivers/ide/at91_ide.c (limited to 'drivers') diff --git a/arch/arm/mach-at91/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c index f1a1bb456a35..5a24f0b4554d 100644 --- a/arch/arm/mach-at91/at91sam9260_devices.c +++ b/arch/arm/mach-at91/at91sam9260_devices.c @@ -1215,8 +1215,7 @@ void __init at91_add_device_serial(void) {} * CF/IDE * -------------------------------------------------------------------- */ -#if defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) || \ - defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \ +#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \ defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) static struct at91_cf_data cf0_data; @@ -1313,10 +1312,8 @@ void __init at91_add_device_cf(struct at91_cf_data *data) if (data->flags & AT91_CF_TRUE_IDE) #if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) pdev->name = "pata_at91"; -#elif defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) - pdev->name = "at91_ide"; #else -#warning "board requires AT91_CF_TRUE_IDE: enable either at91_ide or pata_at91" +#warning "board requires AT91_CF_TRUE_IDE: enable pata_at91" #endif else pdev->name = "at91_cf"; diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c index 618013de543d..366a7765635b 100644 --- a/arch/arm/mach-at91/at91sam9263_devices.c +++ b/arch/arm/mach-at91/at91sam9263_devices.c @@ -355,8 +355,8 @@ void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {} * Compact Flash (PCMCIA or IDE) * -------------------------------------------------------------------- */ -#if defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) || \ - defined(CONFIG_BLK_DEV_IDE_AT91) || defined(CONFIG_BLK_DEV_IDE_AT91_MODULE) +#if defined(CONFIG_PATA_AT91) || defined(CONFIG_PATA_AT91_MODULE) || \ + defined(CONFIG_AT91_CF) || defined(CONFIG_AT91_CF_MODULE) static struct at91_cf_data cf0_data; @@ -450,7 +450,7 @@ void __init at91_add_device_cf(struct at91_cf_data *data) at91_set_A_periph(AT91_PIN_PD9, 0); /* CFCE2 */ at91_set_A_periph(AT91_PIN_PD14, 0); /* CFNRW */ - pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "at91_ide" : "at91_cf"; + pdev->name = (data->flags & AT91_CF_TRUE_IDE) ? "pata_at91" : "at91_cf"; platform_device_register(pdev); } #else diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile index 7f879b2397b0..af8d016c37ea 100644 --- a/drivers/ide/Makefile +++ b/drivers/ide/Makefile @@ -116,4 +116,3 @@ obj-$(CONFIG_BLK_DEV_IDE_AU1XXX) += au1xxx-ide.o obj-$(CONFIG_BLK_DEV_IDE_TX4938) += tx4938ide.o obj-$(CONFIG_BLK_DEV_IDE_TX4939) += tx4939ide.o -obj-$(CONFIG_BLK_DEV_IDE_AT91) += at91_ide.o diff --git a/drivers/ide/at91_ide.c b/drivers/ide/at91_ide.c deleted file mode 100644 index 41d415529479..000000000000 --- a/drivers/ide/at91_ide.c +++ /dev/null @@ -1,366 +0,0 @@ -/* - * IDE host driver for AT91 (SAM9, CAP9, AT572D940HF) Static Memory Controller - * with Compact Flash True IDE logic - * - * Copyright (c) 2008, 2009 Kelvatek Ltd. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#define DRV_NAME "at91_ide" - -#define perr(fmt, args...) pr_err(DRV_NAME ": " fmt, ##args) -#define pdbg(fmt, args...) pr_debug("%s " fmt, __func__, ##args) - -/* - * Access to IDE device is possible through EBI Static Memory Controller - * with Compact Flash logic. For details see EBI and SMC datasheet sections - * of any microcontroller from AT91SAM9 family. - * - * Within SMC chip select address space, lines A[23:21] distinguish Compact - * Flash modes (I/O, common memory, attribute memory, True IDE). IDE modes are: - * 0x00c0000 - True IDE - * 0x00e0000 - Alternate True IDE (Alt Status Register) - * - * On True IDE mode Task File and Data Register are mapped at the same address. - * To distinguish access between these two different bus data width is used: - * 8Bit for Task File, 16Bit for Data I/O. - * - * After initialization we do 8/16 bit flipping (changes in SMC MODE register) - * only inside IDE callback routines which are serialized by IDE layer, - * so no additional locking needed. - */ - -#define TASK_FILE 0x00c00000 -#define ALT_MODE 0x00e00000 -#define REGS_SIZE 8 - -#define enter_16bit(cs, mode) do { \ - mode = at91_sys_read(AT91_SMC_MODE(cs)); \ - at91_sys_write(AT91_SMC_MODE(cs), mode | AT91_SMC_DBW_16); \ -} while (0) - -#define leave_16bit(cs, mode) at91_sys_write(AT91_SMC_MODE(cs), mode); - -static void set_smc_timings(const u8 chipselect, const u16 cycle, - const u16 setup, const u16 pulse, - const u16 data_float, int use_iordy) -{ - unsigned long mode = AT91_SMC_READMODE | AT91_SMC_WRITEMODE | - AT91_SMC_BAT_SELECT; - - /* disable or enable waiting for IORDY signal */ - if (use_iordy) - mode |= AT91_SMC_EXNWMODE_READY; - - /* add data float cycles if needed */ - if (data_float) - mode |= AT91_SMC_TDF_(data_float); - - at91_sys_write(AT91_SMC_MODE(chipselect), mode); - - /* setup timings in SMC */ - at91_sys_write(AT91_SMC_SETUP(chipselect), AT91_SMC_NWESETUP_(setup) | - AT91_SMC_NCS_WRSETUP_(0) | - AT91_SMC_NRDSETUP_(setup) | - AT91_SMC_NCS_RDSETUP_(0)); - at91_sys_write(AT91_SMC_PULSE(chipselect), AT91_SMC_NWEPULSE_(pulse) | - AT91_SMC_NCS_WRPULSE_(cycle) | - AT91_SMC_NRDPULSE_(pulse) | - AT91_SMC_NCS_RDPULSE_(cycle)); - at91_sys_write(AT91_SMC_CYCLE(chipselect), AT91_SMC_NWECYCLE_(cycle) | - AT91_SMC_NRDCYCLE_(cycle)); -} - -static unsigned int calc_mck_cycles(unsigned int ns, unsigned int mck_hz) -{ - u64 tmp = ns; - - tmp *= mck_hz; - tmp += 1000*1000*1000 - 1; /* round up */ - do_div(tmp, 1000*1000*1000); - return (unsigned int) tmp; -} - -static void apply_timings(const u8 chipselect, const u8 pio, - const struct ide_timing *timing, int use_iordy) -{ - unsigned int t0, t1, t2, t6z; - unsigned int cycle, setup, pulse, data_float; - unsigned int mck_hz; - struct clk *mck; - - /* see table 22 of Compact Flash standard 4.1 for the meaning, - * we do not stretch active (t2) time, so setup (t1) + hold time (th) - * assure at least minimal recovery (t2i) time */ - t0 = timing->cyc8b; - t1 = timing->setup; - t2 = timing->act8b; - t6z = (pio < 5) ? 30 : 20; - - pdbg("t0=%u t1=%u t2=%u t6z=%u\n", t0, t1, t2, t6z); - - mck = clk_get(NULL, "mck"); - BUG_ON(IS_ERR(mck)); - mck_hz = clk_get_rate(mck); - pdbg("mck_hz=%u\n", mck_hz); - - cycle = calc_mck_cycles(t0, mck_hz); - setup = calc_mck_cycles(t1, mck_hz); - pulse = calc_mck_cycles(t2, mck_hz); - data_float = calc_mck_cycles(t6z, mck_hz); - - pdbg("cycle=%u setup=%u pulse=%u data_float=%u\n", - cycle, setup, pulse, data_float); - - set_smc_timings(chipselect, cycle, setup, pulse, data_float, use_iordy); -} - -static void at91_ide_input_data(ide_drive_t *drive, struct ide_cmd *cmd, - void *buf, unsigned int len) -{ - ide_hwif_t *hwif = drive->hwif; - struct ide_io_ports *io_ports = &hwif->io_ports; - u8 chipselect = hwif->select_data; - unsigned long mode; - - pdbg("cs %u buf %p len %d\n", chipselect, buf, len); - - len++; - - enter_16bit(chipselect, mode); - readsw((void __iomem *)io_ports->data_addr, buf, len / 2); - leave_16bit(chipselect, mode); -} - -static void at91_ide_output_data(ide_drive_t *drive, struct ide_cmd *cmd, - void *buf, unsigned int len) -{ - ide_hwif_t *hwif = drive->hwif; - struct ide_io_ports *io_ports = &hwif->io_ports; - u8 chipselect = hwif->select_data; - unsigned long mode; - - pdbg("cs %u buf %p len %d\n", chipselect, buf, len); - - enter_16bit(chipselect, mode); - writesw((void __iomem *)io_ports->data_addr, buf, len / 2); - leave_16bit(chipselect, mode); -} - -static void at91_ide_set_pio_mode(ide_hwif_t *hwif, ide_drive_t *drive) -{ - struct ide_timing *timing; - u8 chipselect = hwif->select_data; - int use_iordy = 0; - const u8 pio = drive->pio_mode - XFER_PIO_0; - - pdbg("chipselect %u pio %u\n", chipselect, pio); - - timing = ide_timing_find_mode(XFER_PIO_0 + pio); - BUG_ON(!timing); - - if (ide_pio_need_iordy(drive, pio)) - use_iordy = 1; - - apply_timings(chipselect, pio, timing, use_iordy); -} - -static const struct ide_tp_ops at91_ide_tp_ops = { - .exec_command = ide_exec_command, - .read_status = ide_read_status, - .read_altstatus = ide_read_altstatus, - .write_devctl = ide_write_devctl, - - .dev_select = ide_dev_select, - .tf_load = ide_tf_load, - .tf_read = ide_tf_read, - - .input_data = at91_ide_input_data, - .output_data = at91_ide_output_data, -}; - -static const struct ide_port_ops at91_ide_port_ops = { - .set_pio_mode = at91_ide_set_pio_mode, -}; - -static const struct ide_port_info at91_ide_port_info __initdata = { - .port_ops = &at91_ide_port_ops, - .tp_ops = &at91_ide_tp_ops, - .host_flags = IDE_HFLAG_MMIO | IDE_HFLAG_NO_DMA | IDE_HFLAG_SINGLE | - IDE_HFLAG_NO_IO_32BIT | IDE_HFLAG_UNMASK_IRQS, - .pio_mask = ATA_PIO6, - .chipset = ide_generic, -}; - -/* - * If interrupt is delivered through GPIO, IRQ are triggered on falling - * and rising edge of signal. Whereas IDE device request interrupt on high - * level (rising edge in our case). This mean we have fake interrupts, so - * we need to check interrupt pin and exit instantly from ISR when line - * is on low level. - */ - -irqreturn_t at91_irq_handler(int irq, void *dev_id) -{ - int ntries = 8; - int pin_val1, pin_val2; - - /* additional deglitch, line can be noisy in badly designed PCB */ - do { - pin_val1 = at91_get_gpio_value(irq); - pin_val2 = at91_get_gpio_value(irq); - } while (pin_val1 != pin_val2 && --ntries > 0); - - if (pin_val1 == 0 || ntries <= 0) - return IRQ_HANDLED; - - return ide_intr(irq, dev_id); -} - -static int __init at91_ide_probe(struct platform_device *pdev) -{ - int ret; - struct ide_hw hw, *hws[] = { &hw }; - struct ide_host *host; - struct resource *res; - unsigned long tf_base = 0, ctl_base = 0; - struct at91_cf_data *board = pdev->dev.platform_data; - - if (!board) - return -ENODEV; - - if (board->det_pin && at91_get_gpio_value(board->det_pin) != 0) { - perr("no device detected\n"); - return -ENODEV; - } - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - perr("can't get memory resource\n"); - return -ENODEV; - } - - if (!devm_request_mem_region(&pdev->dev, res->start + TASK_FILE, - REGS_SIZE, "ide") || - !devm_request_mem_region(&pdev->dev, res->start + ALT_MODE, - REGS_SIZE, "alt")) { - perr("memory resources in use\n"); - return -EBUSY; - } - - pdbg("chipselect %u irq %u res %08lx\n", board->chipselect, - board->irq_pin, (unsigned long) res->start); - - tf_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + TASK_FILE, - REGS_SIZE); - ctl_base = (unsigned long) devm_ioremap(&pdev->dev, res->start + ALT_MODE, - REGS_SIZE); - if (!tf_base || !ctl_base) { - perr("can't map memory regions\n"); - return -EBUSY; - } - - memset(&hw, 0, sizeof(hw)); - - if (board->flags & AT91_IDE_SWAP_A0_A2) { - /* workaround for stupid hardware bug */ - hw.io_ports.data_addr = tf_base + 0; - hw.io_ports.error_addr = tf_base + 4; - hw.io_ports.nsect_addr = tf_base + 2; - hw.io_ports.lbal_addr = tf_base + 6; - hw.io_ports.lbam_addr = tf_base + 1; - hw.io_ports.lbah_addr = tf_base + 5; - hw.io_ports.device_addr = tf_base + 3; - hw.io_ports.command_addr = tf_base + 7; - hw.io_ports.ctl_addr = ctl_base + 3; - } else - ide_std_init_ports(&hw, tf_base, ctl_base + 6); - - hw.irq = board->irq_pin; - hw.dev = &pdev->dev; - - host = ide_host_alloc(&at91_ide_port_info, hws, 1); - if (!host) { - perr("failed to allocate ide host\n"); - return -ENOMEM; - } - - /* setup Static Memory Controller - PIO 0 as default */ - apply_timings(board->chipselect, 0, ide_timing_find_mode(XFER_PIO_0), 0); - - /* with GPIO interrupt we have to do quirks in handler */ - if (gpio_is_valid(board->irq_pin)) - host->irq_handler = at91_irq_handler; - - host->ports[0]->select_data = board->chipselect; - - ret = ide_host_register(host, &at91_ide_port_info, hws); - if (ret) { - perr("failed to register ide host\n"); - goto err_free_host; - } - platform_set_drvdata(pdev, host); - return 0; - -err_free_host: - ide_host_free(host); - return ret; -} - -static int __exit at91_ide_remove(struct platform_device *pdev) -{ - struct ide_host *host = platform_get_drvdata(pdev); - - ide_host_remove(host); - return 0; -} - -static struct platform_driver at91_ide_driver = { - .driver = { - .name = DRV_NAME, - .owner = THIS_MODULE, - }, - .remove = __exit_p(at91_ide_remove), -}; - -static int __init at91_ide_init(void) -{ - return platform_driver_probe(&at91_ide_driver, at91_ide_probe); -} - -static void __exit at91_ide_exit(void) -{ - platform_driver_unregister(&at91_ide_driver); -} - -module_init(at91_ide_init); -module_exit(at91_ide_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Stanislaw Gruszka "); - -- cgit v1.2.3-59-g8ed1b From 758ff235b3f50f0cb391ba3c5e10793305c42f45 Mon Sep 17 00:00:00 2001 From: Axel Lin Date: Sun, 12 Feb 2012 15:14:39 +0000 Subject: mlx4: Fix kcalloc parameters swapped The first parameter should be "number of elements" and the second parameter should be "element size". Signed-off-by: Axel Lin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/eq.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/eq.c b/drivers/net/ethernet/mellanox/mlx4/eq.c index 55d7bd4e210a..8fa41f3082cf 100644 --- a/drivers/net/ethernet/mellanox/mlx4/eq.c +++ b/drivers/net/ethernet/mellanox/mlx4/eq.c @@ -815,8 +815,9 @@ int mlx4_init_eq_table(struct mlx4_dev *dev) int err; int i; - priv->eq_table.uar_map = kcalloc(sizeof *priv->eq_table.uar_map, - mlx4_num_eq_uar(dev), GFP_KERNEL); + priv->eq_table.uar_map = kcalloc(mlx4_num_eq_uar(dev), + sizeof *priv->eq_table.uar_map, + GFP_KERNEL); if (!priv->eq_table.uar_map) { err = -ENOMEM; goto err_out_free; -- cgit v1.2.3-59-g8ed1b From a19c5d68410a90c19521d966c88939700c4a1b3d Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 13 Feb 2012 01:23:20 +0000 Subject: cpmac: fix PHY name to match MDIO bus name Commit d1733f07: cpmac: use an unique MDIO bus name changed the MDIO bus name from "1" to "cpmac-1", this breaks the PHY connection logic because the PHY name still uses the old bus names "0" and "1", fix that to always use the mdio bus id instead. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/ti/cpmac.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c index 4d9a28ffd3c3..cbc8df78d84b 100644 --- a/drivers/net/ethernet/ti/cpmac.c +++ b/drivers/net/ethernet/ti/cpmac.c @@ -1122,7 +1122,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev) pdata = pdev->dev.platform_data; if (external_switch || dumb_switch) { - strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */ + strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */ phy_id = pdev->id; } else { for (phy_id = 0; phy_id < PHY_MAX_ADDR; phy_id++) { @@ -1138,7 +1138,7 @@ static int __devinit cpmac_probe(struct platform_device *pdev) if (phy_id == PHY_MAX_ADDR) { dev_err(&pdev->dev, "no PHY present, falling back " "to switch on MDIO bus 0\n"); - strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); /* fixed phys bus */ + strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); /* fixed phys bus */ phy_id = pdev->id; } -- cgit v1.2.3-59-g8ed1b From c56e9e2ae766b687ed66c3c9c3bb6b2ee15405b2 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 13 Feb 2012 01:23:21 +0000 Subject: bcm63xx-enet: fix PHY name to match MDIO bus name Commit 3e617506: bcm63xx_enet: use an unique MDIO bus name introduced a regression in the PHY connection logic, since the PHY name was formatted to expect the bus name to be "0" or "1", whereas it is now "bcm63xx-enet-0" or "bcm63xx-enet-1". Reported-by: Joel EJC Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bcm63xx_enet.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 986019b2c849..c7ca7ec065ee 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -797,7 +797,7 @@ static int bcm_enet_open(struct net_device *dev) if (priv->has_phy) { /* connect to PHY */ snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, - priv->mac_id ? "1" : "0", priv->phy_id); + priv->mii_bus->id, priv->phy_id); phydev = phy_connect(dev, phy_id, bcm_enet_adjust_phy_link, 0, PHY_INTERFACE_MODE_MII); -- cgit v1.2.3-59-g8ed1b From ea51ade9398f3c94f63a25f512445ee7cbbbf284 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 13 Feb 2012 01:23:22 +0000 Subject: fec: fix PHY name to match fixed MDIO bus name Commit "391420f7: fec: use an unique MDIO bus name" first modified the MDIO bus name to include the platform name, then in commit "a7ed07d5: net: fec: correct phy_name buffer length when init phy_name" the PHY name formatting was fixed in the case the PHY matches a PHY driver. The FEC driver however, also handles the case where we want to attach to the fixed MDIO bus name, which was previously named "0", and now "fixed-0". Change the PHY formatting logic to account for that. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/freescale/fec.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/freescale/fec.c b/drivers/net/ethernet/freescale/fec.c index 1c7aad8fa19c..e92ef1bd732a 100644 --- a/drivers/net/ethernet/freescale/fec.c +++ b/drivers/net/ethernet/freescale/fec.c @@ -986,7 +986,7 @@ static int fec_enet_mii_probe(struct net_device *ndev) printk(KERN_INFO "%s: no PHY, assuming direct connection to switch\n", ndev->name); - strncpy(mdio_bus_id, "0", MII_BUS_ID_SIZE); + strncpy(mdio_bus_id, "fixed-0", MII_BUS_ID_SIZE); phy_id = 0; } -- cgit v1.2.3-59-g8ed1b From b0c06e12b6f1dad480c459ddc5412a0fd8582201 Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 13 Feb 2012 01:23:23 +0000 Subject: octeon: fix PHY name to match MDIO bus name Commit "d6c25be: mdio-octeon: use an unique MDIO bus name" changed the octeon MDIO bus name from "0" to "mdio-octeon-0", change the PHY formatting logic to account for that name change, so that PHY connection on this bus succeeds. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/octeon/octeon_mgmt.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/octeon/octeon_mgmt.c b/drivers/net/ethernet/octeon/octeon_mgmt.c index 212f43b308a3..cd827ff4a021 100644 --- a/drivers/net/ethernet/octeon/octeon_mgmt.c +++ b/drivers/net/ethernet/octeon/octeon_mgmt.c @@ -670,7 +670,7 @@ static void octeon_mgmt_adjust_link(struct net_device *netdev) static int octeon_mgmt_init_phy(struct net_device *netdev) { struct octeon_mgmt *p = netdev_priv(netdev); - char phy_id[20]; + char phy_id[MII_BUS_ID_SIZE + 3]; if (octeon_is_simulation()) { /* No PHYs in the simulator. */ @@ -678,7 +678,7 @@ static int octeon_mgmt_init_phy(struct net_device *netdev) return 0; } - snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "0", p->port); + snprintf(phy_id, sizeof(phy_id), PHY_ID_FMT, "mdio-octeon-0", p->port); p->phydev = phy_connect(netdev, phy_id, octeon_mgmt_adjust_link, 0, PHY_INTERFACE_MODE_MII); -- cgit v1.2.3-59-g8ed1b From 7465ac3c2f2c99b3c69bd8e257758a0baa7bc7ea Mon Sep 17 00:00:00 2001 From: Florian Fainelli Date: Mon, 13 Feb 2012 01:23:24 +0000 Subject: ixp4xx-eth: fix PHY name to match MDIO bus name Commit 0869b3a4: ixp4xx-eth: use an unique MDIO bus name changed the MDIO bus name from "0" to "ixp4xx-eth-0", as a result the PHY name is not longer appropriate and will not match the MDIO bus name so PHY connection will not succeed, fix that. Signed-off-by: Florian Fainelli Signed-off-by: David S. Miller --- drivers/net/ethernet/xscale/ixp4xx_eth.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 72a854f05bb8..41a8b5a9849e 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -1416,7 +1416,8 @@ static int __devinit eth_init_one(struct platform_device *pdev) __raw_writel(DEFAULT_CORE_CNTRL, &port->regs->core_control); udelay(50); - snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, "0", plat->phy); + snprintf(phy_id, MII_BUS_ID_SIZE + 3, PHY_ID_FMT, + mdio_bus->id, plat->phy); port->phydev = phy_connect(dev, phy_id, &ixp4xx_adjust_link, 0, PHY_INTERFACE_MODE_MII); if (IS_ERR(port->phydev)) { -- cgit v1.2.3-59-g8ed1b From 66d885cba670059396b2f9ed9d5f4cbead0baee0 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Mon, 13 Feb 2012 06:23:12 +0000 Subject: bnx2x: fix bnx2x_storm_stats_update() on big endian commit 619c5cb6885 (New 7.0 FW: bnx2x, cnic, bnx2i, bnx2fc) added new sparse warnings. Signed-off-by: Eric Dumazet Cc: Eilon Greenstein Cc: Vladislav Zolotarov Cc: Michael Chan Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c index bc0121ac291e..1adef266fcd5 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_stats.c @@ -1081,17 +1081,17 @@ static int bnx2x_storm_stats_update(struct bnx2x *bp) estats->rx_stat_ifhcinbadoctets_lo); ADD_64(fstats->total_bytes_received_hi, - tfunc->rcv_error_bytes.hi, + le32_to_cpu(tfunc->rcv_error_bytes.hi), fstats->total_bytes_received_lo, - tfunc->rcv_error_bytes.lo); + le32_to_cpu(tfunc->rcv_error_bytes.lo)); memcpy(estats, &(fstats->total_bytes_received_hi), sizeof(struct host_func_stats) - 2*sizeof(u32)); ADD_64(estats->error_bytes_received_hi, - tfunc->rcv_error_bytes.hi, + le32_to_cpu(tfunc->rcv_error_bytes.hi), estats->error_bytes_received_lo, - tfunc->rcv_error_bytes.lo); + le32_to_cpu(tfunc->rcv_error_bytes.lo)); ADD_64(estats->etherstatsoverrsizepkts_hi, estats->rx_stat_dot3statsframestoolong_hi, -- cgit v1.2.3-59-g8ed1b From fbcf88b8833ce2c404b9a0e7caab82b20312cbbc Mon Sep 17 00:00:00 2001 From: "Cousson, Benoit" Date: Mon, 13 Feb 2012 07:37:12 +0000 Subject: ks8851: Fix NOHZ local_softirq_pending 08 warning This fix a similar problem as in 72092cc45378176ba700034c91b7af2db524df26 and 481a8199142c050b72bff8a1956a49fd0a75bbe0 ("can: fix NOHZ local_softirq_pending 08 warning"). This fix replaces netif_rx() with netif_rx_ni() which has to be used from process/softirq context. Signed-off-by: Benoit Cousson Cc: David S. Miller Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8851.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/micrel/ks8851.c b/drivers/net/ethernet/micrel/ks8851.c index 6b35e7da9a9c..0c3e4005224d 100644 --- a/drivers/net/ethernet/micrel/ks8851.c +++ b/drivers/net/ethernet/micrel/ks8851.c @@ -583,7 +583,7 @@ static void ks8851_rx_pkts(struct ks8851_net *ks) ks8851_dbg_dumpkkt(ks, rxpkt); skb->protocol = eth_type_trans(skb, ks->netdev); - netif_rx(skb); + netif_rx_ni(skb); ks->netdev->stats.rx_packets++; ks->netdev->stats.rx_bytes += rxlen; -- cgit v1.2.3-59-g8ed1b From 2d0d68f583279dbdcc1a2ef3f81ea8d285a0adbe Mon Sep 17 00:00:00 2001 From: Philip Rakity Date: Thu, 26 Jan 2012 06:57:10 -0800 Subject: mmc: core: UHS sdio card that fails should not exceed 50MHz A UHS sdio card that fails initialization at 1.8v signaling is not in UHS mode. We cannot use the speed in the the cis to reflect the bus speed as this is the maxiumum value and will not reflect the fact that the host is operating at a lower (non uhs) bus speed. Signed-off-by: Philip Rakity Signed-off-by: Bing Zhao Reviewed-by: Aaron Lu Signed-off-by: Chris Ball --- drivers/mmc/core/sdio.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/sdio.c b/drivers/mmc/core/sdio.c index bd7bacc950dc..12cde6ee17f5 100644 --- a/drivers/mmc/core/sdio.c +++ b/drivers/mmc/core/sdio.c @@ -98,10 +98,11 @@ fail: return ret; } -static int sdio_read_cccr(struct mmc_card *card) +static int sdio_read_cccr(struct mmc_card *card, u32 ocr) { int ret; int cccr_vsn; + int uhs = ocr & R4_18V_PRESENT; unsigned char data; unsigned char speed; @@ -149,7 +150,7 @@ static int sdio_read_cccr(struct mmc_card *card) card->scr.sda_spec3 = 0; card->sw_caps.sd3_bus_mode = 0; card->sw_caps.sd3_drv_type = 0; - if (cccr_vsn >= SDIO_CCCR_REV_3_00) { + if (cccr_vsn >= SDIO_CCCR_REV_3_00 && uhs) { card->scr.sda_spec3 = 1; ret = mmc_io_rw_direct(card, 0, 0, SDIO_CCCR_UHS, 0, &data); @@ -712,7 +713,7 @@ static int mmc_sdio_init_card(struct mmc_host *host, u32 ocr, /* * Read the common registers. */ - err = sdio_read_cccr(card); + err = sdio_read_cccr(card, ocr); if (err) goto remove; -- cgit v1.2.3-59-g8ed1b From b6bf30d912ddc9a3ac2ce264a04e3ec6d4e74a34 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Mon, 30 Jan 2012 05:15:29 +0100 Subject: mmc: of_mmc_spi: fix little endian support The voltage_ranges is supposed to switch from big endian to little endian. Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Grant Likely Signed-off-by: Chris Ball --- drivers/mmc/host/of_mmc_spi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/of_mmc_spi.c b/drivers/mmc/host/of_mmc_spi.c index ab66f2454dc4..1534b582c419 100644 --- a/drivers/mmc/host/of_mmc_spi.c +++ b/drivers/mmc/host/of_mmc_spi.c @@ -113,8 +113,8 @@ struct mmc_spi_platform_data *mmc_spi_get_pdata(struct spi_device *spi) const int j = i * 2; u32 mask; - mask = mmc_vddrange_to_ocrmask(voltage_ranges[j], - voltage_ranges[j + 1]); + mask = mmc_vddrange_to_ocrmask(be32_to_cpu(voltage_ranges[j]), + be32_to_cpu(voltage_ranges[j + 1])); if (!mask) { ret = -EINVAL; dev_err(dev, "OF: voltage-range #%d is invalid\n", i); -- cgit v1.2.3-59-g8ed1b From 2c4967f741e87cdd63de7271b97807041dccbf3b Mon Sep 17 00:00:00 2001 From: Sujit Reddy Thumma Date: Sat, 4 Feb 2012 16:14:50 -0500 Subject: mmc: core: Ensure clocks are always enabled before host interaction Ensure clocks are always enabled before any interaction with the host controller driver. This makes sure that there is no race between host execution and the core layer turning off clocks in different context with clock gating framework. Signed-off-by: Sujit Reddy Thumma Acked-by: Linus Walleij Acked-by: Per Forlin Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 19 ++++++++++++++++--- drivers/mmc/core/host.h | 21 --------------------- drivers/mmc/core/sd.c | 22 ++++++++++++++++++---- drivers/mmc/core/sdio_irq.c | 10 ++++++++-- include/linux/mmc/host.h | 19 +++++++++++++++++++ 5 files changed, 61 insertions(+), 30 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index f545a3e6eb80..b3063b741df3 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -290,8 +290,11 @@ static void mmc_wait_for_req_done(struct mmc_host *host, static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq, bool is_first_req) { - if (host->ops->pre_req) + if (host->ops->pre_req) { + mmc_host_clk_hold(host); host->ops->pre_req(host, mrq, is_first_req); + mmc_host_clk_release(host); + } } /** @@ -306,8 +309,11 @@ static void mmc_pre_req(struct mmc_host *host, struct mmc_request *mrq, static void mmc_post_req(struct mmc_host *host, struct mmc_request *mrq, int err) { - if (host->ops->post_req) + if (host->ops->post_req) { + mmc_host_clk_hold(host); host->ops->post_req(host, mrq, err); + mmc_host_clk_release(host); + } } /** @@ -620,7 +626,9 @@ int mmc_host_enable(struct mmc_host *host) int err; host->en_dis_recurs = 1; + mmc_host_clk_hold(host); err = host->ops->enable(host); + mmc_host_clk_release(host); host->en_dis_recurs = 0; if (err) { @@ -640,7 +648,9 @@ static int mmc_host_do_disable(struct mmc_host *host, int lazy) int err; host->en_dis_recurs = 1; + mmc_host_clk_hold(host); err = host->ops->disable(host, lazy); + mmc_host_clk_release(host); host->en_dis_recurs = 0; if (err < 0) { @@ -1203,8 +1213,11 @@ int mmc_set_signal_voltage(struct mmc_host *host, int signal_voltage, bool cmd11 host->ios.signal_voltage = signal_voltage; - if (host->ops->start_signal_voltage_switch) + if (host->ops->start_signal_voltage_switch) { + mmc_host_clk_hold(host); err = host->ops->start_signal_voltage_switch(host, &host->ios); + mmc_host_clk_release(host); + } return err; } diff --git a/drivers/mmc/core/host.h b/drivers/mmc/core/host.h index fb8a5cd2e4a1..08a7852ade44 100644 --- a/drivers/mmc/core/host.h +++ b/drivers/mmc/core/host.h @@ -14,27 +14,6 @@ int mmc_register_host_class(void); void mmc_unregister_host_class(void); - -#ifdef CONFIG_MMC_CLKGATE -void mmc_host_clk_hold(struct mmc_host *host); -void mmc_host_clk_release(struct mmc_host *host); -unsigned int mmc_host_clk_rate(struct mmc_host *host); - -#else -static inline void mmc_host_clk_hold(struct mmc_host *host) -{ -} - -static inline void mmc_host_clk_release(struct mmc_host *host) -{ -} - -static inline unsigned int mmc_host_clk_rate(struct mmc_host *host) -{ - return host->ios.clock; -} -#endif - void mmc_host_deeper_disable(struct work_struct *work); #endif diff --git a/drivers/mmc/core/sd.c b/drivers/mmc/core/sd.c index c63ad03c29c7..5017f9354ce2 100644 --- a/drivers/mmc/core/sd.c +++ b/drivers/mmc/core/sd.c @@ -451,9 +451,11 @@ static int sd_select_driver_type(struct mmc_card *card, u8 *status) * information and let the hardware specific code * return what is possible given the options */ + mmc_host_clk_hold(card->host); drive_strength = card->host->ops->select_drive_strength( card->sw_caps.uhs_max_dtr, host_drv_type, card_drv_type); + mmc_host_clk_release(card->host); err = mmc_sd_switch(card, 1, 2, drive_strength, status); if (err) @@ -660,9 +662,12 @@ static int mmc_sd_init_uhs_card(struct mmc_card *card) goto out; /* SPI mode doesn't define CMD19 */ - if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) + if (!mmc_host_is_spi(card->host) && card->host->ops->execute_tuning) { + mmc_host_clk_hold(card->host); err = card->host->ops->execute_tuning(card->host, MMC_SEND_TUNING_BLOCK); + mmc_host_clk_release(card->host); + } out: kfree(status); @@ -850,8 +855,11 @@ int mmc_sd_setup_card(struct mmc_host *host, struct mmc_card *card, if (!reinit) { int ro = -1; - if (host->ops->get_ro) + if (host->ops->get_ro) { + mmc_host_clk_hold(card->host); ro = host->ops->get_ro(host); + mmc_host_clk_release(card->host); + } if (ro < 0) { pr_warning("%s: host does not " @@ -967,8 +975,11 @@ static int mmc_sd_init_card(struct mmc_host *host, u32 ocr, * Since initialization is now complete, enable preset * value registers for UHS-I cards. */ - if (host->ops->enable_preset_value) + if (host->ops->enable_preset_value) { + mmc_host_clk_hold(card->host); host->ops->enable_preset_value(host, true); + mmc_host_clk_release(card->host); + } } else { /* * Attempt to change to high-speed (if supported) @@ -1151,8 +1162,11 @@ int mmc_attach_sd(struct mmc_host *host) return err; /* Disable preset value enable if already set since last time */ - if (host->ops->enable_preset_value) + if (host->ops->enable_preset_value) { + mmc_host_clk_hold(host); host->ops->enable_preset_value(host, false); + mmc_host_clk_release(host); + } err = mmc_send_app_op_cond(host, 0, &ocr); if (err) diff --git a/drivers/mmc/core/sdio_irq.c b/drivers/mmc/core/sdio_irq.c index 68f81b9ee0fb..f573e7f9f740 100644 --- a/drivers/mmc/core/sdio_irq.c +++ b/drivers/mmc/core/sdio_irq.c @@ -146,15 +146,21 @@ static int sdio_irq_thread(void *_host) } set_current_state(TASK_INTERRUPTIBLE); - if (host->caps & MMC_CAP_SDIO_IRQ) + if (host->caps & MMC_CAP_SDIO_IRQ) { + mmc_host_clk_hold(host); host->ops->enable_sdio_irq(host, 1); + mmc_host_clk_release(host); + } if (!kthread_should_stop()) schedule_timeout(period); set_current_state(TASK_RUNNING); } while (!kthread_should_stop()); - if (host->caps & MMC_CAP_SDIO_IRQ) + if (host->caps & MMC_CAP_SDIO_IRQ) { + mmc_host_clk_hold(host); host->ops->enable_sdio_irq(host, 0); + mmc_host_clk_release(host); + } pr_debug("%s: IRQ thread exiting with code %d\n", mmc_hostname(host), ret); diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 0beba1e5e1ed..73e5ee8e9ca2 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -444,4 +444,23 @@ static inline int mmc_boot_partition_access(struct mmc_host *host) return !(host->caps2 & MMC_CAP2_BOOTPART_NOACC); } +#ifdef CONFIG_MMC_CLKGATE +void mmc_host_clk_hold(struct mmc_host *host); +void mmc_host_clk_release(struct mmc_host *host); +unsigned int mmc_host_clk_rate(struct mmc_host *host); + +#else +static inline void mmc_host_clk_hold(struct mmc_host *host) +{ +} + +static inline void mmc_host_clk_release(struct mmc_host *host) +{ +} + +static inline unsigned int mmc_host_clk_rate(struct mmc_host *host) +{ + return host->ios.clock; +} +#endif #endif /* LINUX_MMC_HOST_H */ -- cgit v1.2.3-59-g8ed1b From 81e499224a7ef02e1889736ebb6b432da1735ab6 Mon Sep 17 00:00:00 2001 From: Jerry Huang Date: Mon, 16 Jan 2012 14:13:03 +0800 Subject: mmc: esdhc: add PIO mode support For some FSL ESDHC controllers (e.g. P2020E, Rev1.0), the SDHC can not work on DMA mode because of the hardware bug, so we set a broken dma flag and use PIO mode. Signed-off-by: Jerry Huang Signed-off-by: Gao Guanhua Acked-by: Anton Vorontsov Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-pltfm.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 03970bcb3495..67b9ab075dee 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -2,7 +2,7 @@ * sdhci-pltfm.c Support for SDHCI platform devices * Copyright (c) 2009 Intel Corporation * - * Copyright (c) 2007 Freescale Semiconductor, Inc. + * Copyright (c) 2007, 2011 Freescale Semiconductor, Inc. * Copyright (c) 2009 MontaVista Software, Inc. * * Authors: Xiaobo Xie @@ -71,6 +71,9 @@ void sdhci_get_of_property(struct platform_device *pdev) if (sdhci_of_wp_inverted(np)) host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT; + if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc")) + host->quirks |= SDHCI_QUIRK_BROKEN_DMA; + clk = of_get_property(np, "clock-frequency", &size); if (clk && size == sizeof(*clk) && *clk) pltfm_host->clock = be32_to_cpup(clk); -- cgit v1.2.3-59-g8ed1b From 147c3b338d1029b6624b7dbe7f7bb98f14236f3b Mon Sep 17 00:00:00 2001 From: Jerry Huang Date: Mon, 16 Jan 2012 14:13:04 +0800 Subject: mmc: esdhc: set the timeout to the max value When accessing the card on some FSL platform boards (e.g p2020, p1010, mpc8536), the following error is reported with the timeout value calculated: mmc0: Got data interrupt 0x00000020 even though no data operation was in progress. mmc0: Got data interrupt 0x00000020 even though no data operation was in progress. So we skip the calculation of timeout and use the max value to fix it. Signed-off-by: Jerry Huang Signed-off-by: Gao Guanhua Signed-off-by: Xie Xiaobo Acked-by: Anton Vorontsov Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-pltfm.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pltfm.c b/drivers/mmc/host/sdhci-pltfm.c index 67b9ab075dee..c5c2a48bdd94 100644 --- a/drivers/mmc/host/sdhci-pltfm.c +++ b/drivers/mmc/host/sdhci-pltfm.c @@ -74,6 +74,11 @@ void sdhci_get_of_property(struct platform_device *pdev) if (of_device_is_compatible(np, "fsl,p2020-rev1-esdhc")) host->quirks |= SDHCI_QUIRK_BROKEN_DMA; + if (of_device_is_compatible(np, "fsl,p2020-esdhc") || + of_device_is_compatible(np, "fsl,p1010-esdhc") || + of_device_is_compatible(np, "fsl,mpc8536-esdhc")) + host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL; + clk = of_get_property(np, "clock-frequency", &size); if (clk && size == sizeof(*clk) && *clk) pltfm_host->clock = be32_to_cpup(clk); -- cgit v1.2.3-59-g8ed1b From 7488e924b55002e70f6d8d181f146edac3006b9f Mon Sep 17 00:00:00 2001 From: Girish K S Date: Thu, 19 Jan 2012 08:56:19 +0530 Subject: mmc: core: Fix low speed mmc card detection failure This patch fixes the failure of low speed mmc card detection. Signed-off-by: Girish K S Signed-off-by: Chris Ball --- drivers/mmc/core/mmc.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 59b9ba52e66a..dd3fcac684a3 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1006,7 +1006,8 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, err = mmc_select_hs200(card); else if (host->caps & MMC_CAP_MMC_HIGHSPEED) err = mmc_switch(card, EXT_CSD_CMD_SET_NORMAL, - EXT_CSD_HS_TIMING, 1, 0); + EXT_CSD_HS_TIMING, 1, + card->ext_csd.generic_cmd6_time); if (err && err != -EBADMSG) goto free_card; @@ -1116,7 +1117,7 @@ static int mmc_init_card(struct mmc_host *host, u32 ocr, * Activate wide bus and DDR (if supported). */ if (!mmc_card_hs200(card) && - (card->csd.mmca_vsn >= CSD_SPEC_VER_3) && + (card->csd.mmca_vsn >= CSD_SPEC_VER_4) && (host->caps & (MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA))) { static unsigned ext_csd_bits[][2] = { { EXT_CSD_BUS_WIDTH_8, EXT_CSD_DDR_BUS_WIDTH_8 }, -- cgit v1.2.3-59-g8ed1b From 6e8201f57c9359c9c5dc8f9805c15a4392492a10 Mon Sep 17 00:00:00 2001 From: Jaehoon Chung Date: Mon, 16 Jan 2012 17:49:01 +0900 Subject: mmc: core: add the capability for broken voltage There is an understood mismatch between the voltage the host controller is set to and the voltage supplied to the card by a fixed voltage regulator. Teaching the driver to accept the mismatch is overly complicated. Instead just accept the regulator's voltage. This patch adds MMC_CAP2_BROKEN_VOLTAGE. If the voltage didn't satisfy between min_uV and max_uV, try to change the voltage in core.c. When changing the voltage, maybe use regulator_set_voltage(). In regulator_set_voltage(), check the below condition. /* sanity check */ if (!rdev->desc->ops->set_voltage && !rdev->desc->ops->set_voltage_sel) { ret = -EINVAL; goto out; } If some board should use the fixed-regulator, always return -EINVAL. Then, eMMC didn't initialize always. So if use a fixed-regulator, we need to add the MMC_CAP2_BROKEN_VOLTAGE. Signed-off-by: Jaehoon Chung Signed-off-by: Kyungmin Park Acked-by: Adrian Hunter Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 4 ++++ include/linux/mmc/host.h | 1 + 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index b3063b741df3..18661554e79c 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1131,6 +1131,10 @@ int mmc_regulator_set_ocr(struct mmc_host *mmc, * might not allow this operation */ voltage = regulator_get_voltage(supply); + + if (mmc->caps2 & MMC_CAP2_BROKEN_VOLTAGE) + min_uV = max_uV = voltage; + if (voltage < 0) result = voltage; else if (voltage < min_uV || voltage > max_uV) diff --git a/include/linux/mmc/host.h b/include/linux/mmc/host.h index 73e5ee8e9ca2..ee2b0363c040 100644 --- a/include/linux/mmc/host.h +++ b/include/linux/mmc/host.h @@ -257,6 +257,7 @@ struct mmc_host { #define MMC_CAP2_HS200_1_2V_SDR (1 << 6) /* can support */ #define MMC_CAP2_HS200 (MMC_CAP2_HS200_1_8V_SDR | \ MMC_CAP2_HS200_1_2V_SDR) +#define MMC_CAP2_BROKEN_VOLTAGE (1 << 7) /* Use the broken voltage */ mmc_pm_flag_t pm_caps; /* supported pm features */ unsigned int power_notify_type; -- cgit v1.2.3-59-g8ed1b From 012e4671e445ac1dd04f40c0b974685280bedca3 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 30 Jan 2012 14:27:18 +0200 Subject: mmc: sdhci-pci: set Medfield SDIO as non-removable Set Medfield SDIO as non-removable to avoid un-necessary card detect activity. Signed-off-by: Adrian Hunter Signed-off-by: Chris Ball --- drivers/mmc/host/sdhci-pci.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sdhci-pci.c b/drivers/mmc/host/sdhci-pci.c index 7165e6a09274..6ebdc4010e7c 100644 --- a/drivers/mmc/host/sdhci-pci.c +++ b/drivers/mmc/host/sdhci-pci.c @@ -250,7 +250,7 @@ static int mfd_emmc_probe_slot(struct sdhci_pci_slot *slot) static int mfd_sdio_probe_slot(struct sdhci_pci_slot *slot) { - slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD; + slot->host->mmc->caps |= MMC_CAP_POWER_OFF_CARD | MMC_CAP_NONREMOVABLE; return 0; } -- cgit v1.2.3-59-g8ed1b From 3e73c36b4dc224529d0b0c0d5d69c0dacd793c42 Mon Sep 17 00:00:00 2001 From: Girish K S Date: Tue, 31 Jan 2012 15:44:03 +0530 Subject: mmc: core: Fix PowerOff Notify suspend/resume Modified the mmc_poweroff to resume before sending the poweroff notification command. In sleep mode only AWAKE and RESET commands are allowed, so before sending the poweroff notification command resume from sleep mode and then send the notification command. PowerOff Notify is tested on a Synopsis Designware Host Controller (eMMC 4.5). The suspend to RAM and resume works fine. Signed-off-by: Girish K S Tested-by: Girish K S Reviewed-by: Saugata Das Signed-off-by: Chris Ball --- drivers/mmc/core/core.c | 26 +++++++++++++++++++------- drivers/mmc/core/mmc.c | 17 ++++++++++++----- include/linux/mmc/card.h | 4 ++++ 3 files changed, 35 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/core.c b/drivers/mmc/core/core.c index 18661554e79c..690255c7d4dc 100644 --- a/drivers/mmc/core/core.c +++ b/drivers/mmc/core/core.c @@ -1256,6 +1256,7 @@ static void mmc_poweroff_notify(struct mmc_host *host) int err = 0; card = host->card; + mmc_claim_host(host); /* * Send power notify command only if card @@ -1286,6 +1287,7 @@ static void mmc_poweroff_notify(struct mmc_host *host) /* Set the card state to no notification after the poweroff */ card->poweroff_notify_state = MMC_NO_POWER_NOTIFICATION; } + mmc_release_host(host); } /* @@ -1344,12 +1346,28 @@ static void mmc_power_up(struct mmc_host *host) void mmc_power_off(struct mmc_host *host) { + int err = 0; mmc_host_clk_hold(host); host->ios.clock = 0; host->ios.vdd = 0; - mmc_poweroff_notify(host); + /* + * For eMMC 4.5 device send AWAKE command before + * POWER_OFF_NOTIFY command, because in sleep state + * eMMC 4.5 devices respond to only RESET and AWAKE cmd + */ + if (host->card && mmc_card_is_sleep(host->card) && + host->bus_ops->resume) { + err = host->bus_ops->resume(host); + + if (!err) + mmc_poweroff_notify(host); + else + pr_warning("%s: error %d during resume " + "(continue with poweroff sequence)\n", + mmc_hostname(host), err); + } /* * Reset ocr mask to be the highest possible voltage supported for @@ -2403,12 +2421,6 @@ int mmc_suspend_host(struct mmc_host *host) */ if (mmc_try_claim_host(host)) { if (host->bus_ops->suspend) { - /* - * For eMMC 4.5 device send notify command - * before sleep, because in sleep state eMMC 4.5 - * devices respond to only RESET and AWAKE cmd - */ - mmc_poweroff_notify(host); err = host->bus_ops->suspend(host); } mmc_do_release_host(host); diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index dd3fcac684a3..9be031934e33 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -1316,11 +1316,13 @@ static int mmc_suspend(struct mmc_host *host) BUG_ON(!host->card); mmc_claim_host(host); - if (mmc_card_can_sleep(host)) + if (mmc_card_can_sleep(host)) { err = mmc_card_sleep(host); - else if (!mmc_host_is_spi(host)) + if (!err) + mmc_card_set_sleep(host->card); + } else if (!mmc_host_is_spi(host)) mmc_deselect_cards(host); - host->card->state &= ~MMC_STATE_HIGHSPEED; + host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); mmc_release_host(host); return err; @@ -1340,7 +1342,11 @@ static int mmc_resume(struct mmc_host *host) BUG_ON(!host->card); mmc_claim_host(host); - err = mmc_init_card(host, host->ocr, host->card); + if (mmc_card_is_sleep(host->card)) { + err = mmc_card_awake(host); + mmc_card_clr_sleep(host->card); + } else + err = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); return err; @@ -1350,7 +1356,8 @@ static int mmc_power_restore(struct mmc_host *host) { int ret; - host->card->state &= ~MMC_STATE_HIGHSPEED; + host->card->state &= ~(MMC_STATE_HIGHSPEED | MMC_STATE_HIGHSPEED_200); + mmc_card_clr_sleep(host->card); mmc_claim_host(host); ret = mmc_init_card(host, host->ocr, host->card); mmc_release_host(host); diff --git a/include/linux/mmc/card.h b/include/linux/mmc/card.h index 9f22ba572de0..19a41d1737af 100644 --- a/include/linux/mmc/card.h +++ b/include/linux/mmc/card.h @@ -217,6 +217,7 @@ struct mmc_card { #define MMC_CARD_SDXC (1<<6) /* card is SDXC */ #define MMC_CARD_REMOVED (1<<7) /* card has been removed */ #define MMC_STATE_HIGHSPEED_200 (1<<8) /* card is in HS200 mode */ +#define MMC_STATE_SLEEP (1<<9) /* card is in sleep state */ unsigned int quirks; /* card quirks */ #define MMC_QUIRK_LENIENT_FN0 (1<<0) /* allow SDIO FN0 writes outside of the VS CCCR range */ #define MMC_QUIRK_BLKSZ_FOR_BYTE_MODE (1<<1) /* use func->cur_blksize */ @@ -382,6 +383,7 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_sd_card_uhs(c) ((c)->state & MMC_STATE_ULTRAHIGHSPEED) #define mmc_card_ext_capacity(c) ((c)->state & MMC_CARD_SDXC) #define mmc_card_removed(c) ((c) && ((c)->state & MMC_CARD_REMOVED)) +#define mmc_card_is_sleep(c) ((c)->state & MMC_STATE_SLEEP) #define mmc_card_set_present(c) ((c)->state |= MMC_STATE_PRESENT) #define mmc_card_set_readonly(c) ((c)->state |= MMC_STATE_READONLY) @@ -393,7 +395,9 @@ static inline void __maybe_unused remove_quirk(struct mmc_card *card, int data) #define mmc_sd_card_set_uhs(c) ((c)->state |= MMC_STATE_ULTRAHIGHSPEED) #define mmc_card_set_ext_capacity(c) ((c)->state |= MMC_CARD_SDXC) #define mmc_card_set_removed(c) ((c)->state |= MMC_CARD_REMOVED) +#define mmc_card_set_sleep(c) ((c)->state |= MMC_STATE_SLEEP) +#define mmc_card_clr_sleep(c) ((c)->state &= ~MMC_STATE_SLEEP) /* * Quirk add/remove for MMC products. */ -- cgit v1.2.3-59-g8ed1b From dd13b4ed4650bb3a7d6c86b549ab66a6aa0c00d8 Mon Sep 17 00:00:00 2001 From: Jurgen Heeks Date: Wed, 1 Feb 2012 13:30:55 +0100 Subject: mmc: core: Fix comparison issue in mmc_compare_ext_csds Found this issue during code review. Actually, there are two issues which both compensate together in lucky case. In unlucky case the bus width probing might not work as expected. Signed-off-by: Jurgen Heeks Reviewed-by: Namjae Jeon Signed-off-by: Chris Ball --- drivers/mmc/core/mmc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/core/mmc.c b/drivers/mmc/core/mmc.c index 9be031934e33..a48066344fa8 100644 --- a/drivers/mmc/core/mmc.c +++ b/drivers/mmc/core/mmc.c @@ -376,7 +376,7 @@ static int mmc_read_ext_csd(struct mmc_card *card, u8 *ext_csd) } card->ext_csd.raw_hc_erase_gap_size = - ext_csd[EXT_CSD_PARTITION_ATTRIBUTE]; + ext_csd[EXT_CSD_HC_WP_GRP_SIZE]; card->ext_csd.raw_sec_trim_mult = ext_csd[EXT_CSD_SEC_TRIM_MULT]; card->ext_csd.raw_sec_erase_mult = @@ -551,7 +551,7 @@ static int mmc_compare_ext_csds(struct mmc_card *card, unsigned bus_width) goto out; /* only compare read only fields */ - err = (!(card->ext_csd.raw_partition_support == + err = !((card->ext_csd.raw_partition_support == bw_ext_csd[EXT_CSD_PARTITION_SUPPORT]) && (card->ext_csd.raw_erased_mem_count == bw_ext_csd[EXT_CSD_ERASED_MEM_CONT]) && -- cgit v1.2.3-59-g8ed1b From e3de2be7368d2983bd7f7ddb6e9cf5ea32363128 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Fri, 6 Jan 2012 13:06:51 +0100 Subject: mmc: tmio_mmc: fix card eject during IO with DMA When DMA is in use and the card is ejected during IO, DMA transfers have to be terminated, otherwise the dmaengine driver fails to operate properly, when the card is re-inserted. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Chris Ball --- drivers/mmc/host/tmio_mmc.h | 7 ++++++- drivers/mmc/host/tmio_mmc_dma.c | 12 ++++++++++++ drivers/mmc/host/tmio_mmc_pio.c | 6 +++++- 3 files changed, 23 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/tmio_mmc.h b/drivers/mmc/host/tmio_mmc.h index a95e6d901726..f96c536d130a 100644 --- a/drivers/mmc/host/tmio_mmc.h +++ b/drivers/mmc/host/tmio_mmc.h @@ -20,8 +20,8 @@ #include #include #include -#include #include +#include /* Definitions for values the CTRL_SDIO_STATUS register can take. */ #define TMIO_SDIO_STAT_IOIRQ 0x0001 @@ -120,6 +120,7 @@ void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data); void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable); void tmio_mmc_request_dma(struct tmio_mmc_host *host, struct tmio_mmc_data *pdata); void tmio_mmc_release_dma(struct tmio_mmc_host *host); +void tmio_mmc_abort_dma(struct tmio_mmc_host *host); #else static inline void tmio_mmc_start_dma(struct tmio_mmc_host *host, struct mmc_data *data) @@ -140,6 +141,10 @@ static inline void tmio_mmc_request_dma(struct tmio_mmc_host *host, static inline void tmio_mmc_release_dma(struct tmio_mmc_host *host) { } + +static inline void tmio_mmc_abort_dma(struct tmio_mmc_host *host) +{ +} #endif #ifdef CONFIG_PM diff --git a/drivers/mmc/host/tmio_mmc_dma.c b/drivers/mmc/host/tmio_mmc_dma.c index 7a6e6cc8f8b8..8253ec12003e 100644 --- a/drivers/mmc/host/tmio_mmc_dma.c +++ b/drivers/mmc/host/tmio_mmc_dma.c @@ -34,6 +34,18 @@ void tmio_mmc_enable_dma(struct tmio_mmc_host *host, bool enable) #endif } +void tmio_mmc_abort_dma(struct tmio_mmc_host *host) +{ + tmio_mmc_enable_dma(host, false); + + if (host->chan_rx) + dmaengine_terminate_all(host->chan_rx); + if (host->chan_tx) + dmaengine_terminate_all(host->chan_tx); + + tmio_mmc_enable_dma(host, true); +} + static void tmio_mmc_start_dma_rx(struct tmio_mmc_host *host) { struct scatterlist *sg = host->sg_ptr, *sg_tmp; diff --git a/drivers/mmc/host/tmio_mmc_pio.c b/drivers/mmc/host/tmio_mmc_pio.c index abad01b37cfb..5f9ad74fbf80 100644 --- a/drivers/mmc/host/tmio_mmc_pio.c +++ b/drivers/mmc/host/tmio_mmc_pio.c @@ -41,8 +41,8 @@ #include #include #include -#include #include +#include #include "tmio_mmc.h" @@ -246,6 +246,7 @@ static void tmio_mmc_reset_work(struct work_struct *work) /* Ready for new calls */ host->mrq = NULL; + tmio_mmc_abort_dma(host); mmc_request_done(host->mmc, mrq); } @@ -272,6 +273,9 @@ static void tmio_mmc_finish_request(struct tmio_mmc_host *host) host->mrq = NULL; spin_unlock_irqrestore(&host->lock, flags); + if (mrq->cmd->error || (mrq->data && mrq->data->error)) + tmio_mmc_abort_dma(host); + mmc_request_done(host->mmc, mrq); } -- cgit v1.2.3-59-g8ed1b From 5ba85d95cae3837665241e6df12aea83b6bf7c32 Mon Sep 17 00:00:00 2001 From: Guennadi Liakhovetski Date: Sat, 21 Jan 2012 00:41:28 +0100 Subject: mmc: sh_mmcif: fix late delayed work initialisation If the driver is loaded with a card in the slot, mmc_add_host() will schedule an immediate card-detection work, which will start IO and wait for command completion. Usually the kernel first returns to the sh_mmcif probe function, lets it finish and only then schedules the rescan work. But sometimes, expecially under heavy system load, the work will be scheduled immediately before returning to the probe method. In this case it is important for the driver to be fully prepared for IO. For sh_mmcif this means, that also the timeout work has to be initialised before calling mmc_add_host(). It is also better to prepare interrupts beforehand. Besides, since mmc_add_host() does card-detection itself, there is no need to do it again immediately afterwards. Signed-off-by: Guennadi Liakhovetski Signed-off-by: Chris Ball --- drivers/mmc/host/sh_mmcif.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/sh_mmcif.c b/drivers/mmc/host/sh_mmcif.c index f5d8b53be333..352d4797865b 100644 --- a/drivers/mmc/host/sh_mmcif.c +++ b/drivers/mmc/host/sh_mmcif.c @@ -1327,7 +1327,7 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) if (ret < 0) goto clean_up2; - mmc_add_host(mmc); + INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work); sh_mmcif_writel(host->addr, MMCIF_CE_INT_MASK, MASK_ALL); @@ -1338,22 +1338,24 @@ static int __devinit sh_mmcif_probe(struct platform_device *pdev) } ret = request_threaded_irq(irq[1], sh_mmcif_intr, sh_mmcif_irqt, 0, "sh_mmc:int", host); if (ret) { - free_irq(irq[0], host); dev_err(&pdev->dev, "request_irq error (sh_mmc:int)\n"); - goto clean_up3; + goto clean_up4; } - INIT_DELAYED_WORK(&host->timeout_work, mmcif_timeout_work); - - mmc_detect_change(host->mmc, 0); + ret = mmc_add_host(mmc); + if (ret < 0) + goto clean_up5; dev_info(&pdev->dev, "driver version %s\n", DRIVER_VERSION); dev_dbg(&pdev->dev, "chip ver H'%04x\n", sh_mmcif_readl(host->addr, MMCIF_CE_VERSION) & 0x0000ffff); return ret; +clean_up5: + free_irq(irq[1], host); +clean_up4: + free_irq(irq[0], host); clean_up3: - mmc_remove_host(mmc); pm_runtime_suspend(&pdev->dev); clean_up2: pm_runtime_disable(&pdev->dev); -- cgit v1.2.3-59-g8ed1b From 00d9ac08757049f334803b3d4dd202a6b1687dab Mon Sep 17 00:00:00 2001 From: Rabin Vincent Date: Wed, 1 Feb 2012 16:31:56 +0100 Subject: mmc: block: Init ro_lock sysfs attr to fix lockdep warnings Signed-off-by: Rabin Vincent Signed-off-by: Johan Rudholm Signed-off-by: Ulf Hansson Acked-by: Linus Walleij Reviewed-by: Namjae Jeon Signed-off-by: Chris Ball --- drivers/mmc/card/block.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/mmc/card/block.c b/drivers/mmc/card/block.c index 0cad48a284a8..c6a383d0244d 100644 --- a/drivers/mmc/card/block.c +++ b/drivers/mmc/card/block.c @@ -1694,6 +1694,7 @@ static int mmc_add_disk(struct mmc_blk_data *md) md->power_ro_lock.show = power_ro_lock_show; md->power_ro_lock.store = power_ro_lock_store; + sysfs_attr_init(&md->power_ro_lock.attr); md->power_ro_lock.attr.mode = mode; md->power_ro_lock.attr.name = "ro_lock_until_next_power_on"; -- cgit v1.2.3-59-g8ed1b From 18ee684b8ab666329e0a0a72d8b70f16fb0e2243 Mon Sep 17 00:00:00 2001 From: Ludovic Desroches Date: Thu, 9 Feb 2012 11:55:29 +0100 Subject: mmc: atmel-mci: save and restore sdioirq when soft reset is performed Sometimes a software reset is needed. Then some registers are saved and restored but the interrupt mask register is missing. It causes issues with sdio devices whose interrupts are masked after reset. Signed-off-by: Ludovic Desroches Cc: stable Signed-off-by: Nicolas Ferre Signed-off-by: Chris Ball --- drivers/mmc/host/atmel-mci.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'drivers') diff --git a/drivers/mmc/host/atmel-mci.c b/drivers/mmc/host/atmel-mci.c index fcfe1eb5acc8..6985cdb0bb26 100644 --- a/drivers/mmc/host/atmel-mci.c +++ b/drivers/mmc/host/atmel-mci.c @@ -969,11 +969,14 @@ static void atmci_start_request(struct atmel_mci *host, host->data_status = 0; if (host->need_reset) { + iflags = atmci_readl(host, ATMCI_IMR); + iflags &= (ATMCI_SDIOIRQA | ATMCI_SDIOIRQB); atmci_writel(host, ATMCI_CR, ATMCI_CR_SWRST); atmci_writel(host, ATMCI_CR, ATMCI_CR_MCIEN); atmci_writel(host, ATMCI_MR, host->mode_reg); if (host->caps.has_cfg_reg) atmci_writel(host, ATMCI_CFG, host->cfg_reg); + atmci_writel(host, ATMCI_IER, iflags); host->need_reset = false; } atmci_writel(host, ATMCI_SDCR, slot->sdc_reg); -- cgit v1.2.3-59-g8ed1b From f9c2a0dc42a6938ff2a80e55ca2bbd1d5581c72e Mon Sep 17 00:00:00 2001 From: Seungwon Jeon Date: Thu, 9 Feb 2012 14:32:43 +0900 Subject: mmc: dw_mmc: Fix PIO mode with support of highmem Current PIO mode makes a kernel crash with CONFIG_HIGHMEM. Highmem pages have a NULL from sg_virt(sg). This patch fixes the following problem. Unable to handle kernel NULL pointer dereference at virtual address 00000000 pgd = c0004000 [00000000] *pgd=00000000 Internal error: Oops: 817 [#1] PREEMPT SMP Modules linked in: CPU: 0 Not tainted (3.0.15-01423-gdbf465f #589) PC is at dw_mci_pull_data32+0x4c/0x9c LR is at dw_mci_read_data_pio+0x54/0x1f0 pc : [] lr : [] psr: 20000193 sp : c0619d48 ip : c0619d70 fp : c0619d6c r10: 00000000 r9 : 00000002 r8 : 00001000 r7 : 00000200 r6 : 00000000 r5 : e1dd3100 r4 : 00000000 r3 : 65622023 r2 : 0000007f r1 : eeb96000 r0 : e1dd3100 Flags: nzCv IRQs off FIQs on Mode SVC_32 ISA ARM Segment xkernel Control: 10c5387d Table: 61e2004a DAC: 00000015 Process swapper (pid: 0, stack limit = 0xc06182f0) Stack: (0xc0619d48 to 0xc061a000) 9d40: e1dd3100 e1a4f000 00000000 e1dd3100 e1a4f000 00000200 9d60: c0619da4 c0619d70 c035988c c03587e4 c0619d9c e18158f4 e1dd3100 e1dd3100 9d80: 00000020 00000000 00000000 00000020 c06e8a84 00000000 c0619e04 c0619da8 9da0: c0359b24 c0359844 e18158f4 e1dd3164 e1dd3168 e1dd3150 3d02fc79 e1dd3154 9dc0: e1dd3178 00000000 00000020 00000000 e1dd3150 00000000 c10dd7e8 e1a84900 9de0: c061e7cc 00000000 00000000 0000008d c06e8a84 c061e780 c0619e4c c0619e08 9e00: c00c4738 c0359a34 3d02fc79 00000000 c0619e4c c05a1698 c05a1670 c05a165c 9e20: c04de8b0 c061e780 c061e7cc e1a84900 ffffed68 0000008d c0618000 00000000 9e40: c0619e6c c0619e50 c00c48b4 c00c46c8 c061e780 c00423ac c061e7cc ffffed68 9e60: c0619e8c c0619e70 c00c7358 c00c487c 0000008d ffffee38 c0618000 ffffed68 9e80: c0619ea4 c0619e90 c00c4258 c00c72b0 c00423ac ffffee38 c0619ecc c0619ea8 9ea0: c004241c c00c4234 ffffffff f8810000 0000006d 00000002 00000001 7fffffff 9ec0: c0619f44 c0619ed0 c0048bc0 c00423c4 220ae7a9 00000000 386f0d30 0005d3a4 9ee0: c00423ac c10dd0b8 c06f2cd8 c0618000 c0594778 c003a674 7fffffff c0619f44 9f00: 386f0d30 c0619f18 c00a6f94 c005be3c 80000013 ffffffff 386f0d30 0005d3a4 9f20: 386f0d30 0005d2d1 c10dd0a8 c10dd0b8 c06f2cd8 c0618000 c0619f74 c0619f48 9f40: c0345858 c005be00 c00a2440 c0618000 c0618000 c00410d8 c06c1944 c00410fc 9f60: c0594778 c003a674 c0619f9c c0619f78 c004a7e8 c03457b4 c0618000 c06c18f8 9f80: 00000000 c0039c70 c06c18d4 c003a674 c0619fb4 c0619fa0 c04ceafc c004a714 9fa0: c06287b4 c06c18f8 c0619ff4 c0619fb8 c0008b68 c04cea68 c0008578 00000000 9fc0: 00000000 c003a674 00000000 10c5387d c0628658 c003aa78 c062f1c4 4000406a 9fe0: 413fc090 00000000 00000000 c0619ff8 40008044 c0008858 00000000 00000000 Backtrace: [] (dw_mci_pull_data32+0x0/0x9c) from [] (dw_mci_read_data_pio+0x54/0x1f0) r6:00000200 r5:e1a4f000 r4:e1dd3100 [] (dw_mci_read_data_pio+0x0/0x1f0) from [] (dw_mci_interrupt+0xfc/0x4a4) [] (dw_mci_interrupt+0x0/0x4a4) from [] (handle_irq_event_percpu+0x7c/0x1b4) [] (handle_irq_event_percpu+0x0/0x1b4) from [] (handle_irq_event+0x44/0x64) [] (handle_irq_event+0x0/0x64) from [] (handle_fasteoi_irq+0xb4/0x124) r7:ffffed68 r6:c061e7cc r5:c00423ac r4:c061e780 [] (handle_fasteoi_irq+0x0/0x124) from [] (generic_handle_irq+0x30/0x38) r7:ffffed68 r6:c0618000 r5:ffffee38 r4:0000008d [] (generic_handle_irq+0x0/0x38) from [] (asm_do_IRQ+0x64/0xe0) r5:ffffee38 r4:c00423ac [] (asm_do_IRQ+0x0/0xe0) from [] (__irq_svc+0x80/0x14c) Exception stack(0xc0619ed0 to 0xc0619f18) Signed-off-by: Seungwon Jeon Acked-by: Will Newton Cc: stable Signed-off-by: Chris Ball --- drivers/mmc/host/dw_mmc.c | 144 +++++++++++++++++++++++---------------------- include/linux/mmc/dw_mmc.h | 6 +- 2 files changed, 79 insertions(+), 71 deletions(-) (limited to 'drivers') diff --git a/drivers/mmc/host/dw_mmc.c b/drivers/mmc/host/dw_mmc.c index 0e342793ff14..8bec1c36b159 100644 --- a/drivers/mmc/host/dw_mmc.c +++ b/drivers/mmc/host/dw_mmc.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include #include @@ -502,8 +501,14 @@ static void dw_mci_submit_data(struct dw_mci *host, struct mmc_data *data) host->dir_status = DW_MCI_SEND_STATUS; if (dw_mci_submit_data_dma(host, data)) { + int flags = SG_MITER_ATOMIC; + if (host->data->flags & MMC_DATA_READ) + flags |= SG_MITER_TO_SG; + else + flags |= SG_MITER_FROM_SG; + + sg_miter_start(&host->sg_miter, data->sg, data->sg_len, flags); host->sg = data->sg; - host->pio_offset = 0; host->part_buf_start = 0; host->part_buf_count = 0; @@ -972,6 +977,7 @@ static void dw_mci_tasklet_func(unsigned long priv) * generates a block interrupt, hence setting * the scatter-gather pointer to NULL. */ + sg_miter_stop(&host->sg_miter); host->sg = NULL; ctrl = mci_readl(host, CTRL); ctrl |= SDMMC_CTRL_FIFO_RESET; @@ -1311,54 +1317,44 @@ static void dw_mci_pull_data(struct dw_mci *host, void *buf, int cnt) static void dw_mci_read_data_pio(struct dw_mci *host) { - struct scatterlist *sg = host->sg; - void *buf = sg_virt(sg); - unsigned int offset = host->pio_offset; + struct sg_mapping_iter *sg_miter = &host->sg_miter; + void *buf; + unsigned int offset; struct mmc_data *data = host->data; int shift = host->data_shift; u32 status; unsigned int nbytes = 0, len; + unsigned int remain, fcnt; do { - len = host->part_buf_count + - (SDMMC_GET_FCNT(mci_readl(host, STATUS)) << shift); - if (offset + len <= sg->length) { + if (!sg_miter_next(sg_miter)) + goto done; + + host->sg = sg_miter->__sg; + buf = sg_miter->addr; + remain = sg_miter->length; + offset = 0; + + do { + fcnt = (SDMMC_GET_FCNT(mci_readl(host, STATUS)) + << shift) + host->part_buf_count; + len = min(remain, fcnt); + if (!len) + break; dw_mci_pull_data(host, (void *)(buf + offset), len); - offset += len; nbytes += len; - - if (offset == sg->length) { - flush_dcache_page(sg_page(sg)); - host->sg = sg = sg_next(sg); - if (!sg) - goto done; - - offset = 0; - buf = sg_virt(sg); - } - } else { - unsigned int remaining = sg->length - offset; - dw_mci_pull_data(host, (void *)(buf + offset), - remaining); - nbytes += remaining; - - flush_dcache_page(sg_page(sg)); - host->sg = sg = sg_next(sg); - if (!sg) - goto done; - - offset = len - remaining; - buf = sg_virt(sg); - dw_mci_pull_data(host, buf, offset); - nbytes += offset; - } + remain -= len; + } while (remain); + sg_miter->consumed = offset; status = mci_readl(host, MINTSTS); mci_writel(host, RINTSTS, SDMMC_INT_RXDR); if (status & DW_MCI_DATA_ERROR_FLAGS) { host->data_status = status; data->bytes_xfered += nbytes; + sg_miter_stop(sg_miter); + host->sg = NULL; smp_wmb(); set_bit(EVENT_DATA_ERROR, &host->pending_events); @@ -1367,65 +1363,66 @@ static void dw_mci_read_data_pio(struct dw_mci *host) return; } } while (status & SDMMC_INT_RXDR); /*if the RXDR is ready read again*/ - host->pio_offset = offset; data->bytes_xfered += nbytes; + + if (!remain) { + if (!sg_miter_next(sg_miter)) + goto done; + sg_miter->consumed = 0; + } + sg_miter_stop(sg_miter); return; done: data->bytes_xfered += nbytes; + sg_miter_stop(sg_miter); + host->sg = NULL; smp_wmb(); set_bit(EVENT_XFER_COMPLETE, &host->pending_events); } static void dw_mci_write_data_pio(struct dw_mci *host) { - struct scatterlist *sg = host->sg; - void *buf = sg_virt(sg); - unsigned int offset = host->pio_offset; + struct sg_mapping_iter *sg_miter = &host->sg_miter; + void *buf; + unsigned int offset; struct mmc_data *data = host->data; int shift = host->data_shift; u32 status; unsigned int nbytes = 0, len; + unsigned int fifo_depth = host->fifo_depth; + unsigned int remain, fcnt; do { - len = ((host->fifo_depth - - SDMMC_GET_FCNT(mci_readl(host, STATUS))) << shift) - - host->part_buf_count; - if (offset + len <= sg->length) { + if (!sg_miter_next(sg_miter)) + goto done; + + host->sg = sg_miter->__sg; + buf = sg_miter->addr; + remain = sg_miter->length; + offset = 0; + + do { + fcnt = ((fifo_depth - + SDMMC_GET_FCNT(mci_readl(host, STATUS))) + << shift) - host->part_buf_count; + len = min(remain, fcnt); + if (!len) + break; host->push_data(host, (void *)(buf + offset), len); - offset += len; nbytes += len; - if (offset == sg->length) { - host->sg = sg = sg_next(sg); - if (!sg) - goto done; - - offset = 0; - buf = sg_virt(sg); - } - } else { - unsigned int remaining = sg->length - offset; - - host->push_data(host, (void *)(buf + offset), - remaining); - nbytes += remaining; - - host->sg = sg = sg_next(sg); - if (!sg) - goto done; - - offset = len - remaining; - buf = sg_virt(sg); - host->push_data(host, (void *)buf, offset); - nbytes += offset; - } + remain -= len; + } while (remain); + sg_miter->consumed = offset; status = mci_readl(host, MINTSTS); mci_writel(host, RINTSTS, SDMMC_INT_TXDR); if (status & DW_MCI_DATA_ERROR_FLAGS) { host->data_status = status; data->bytes_xfered += nbytes; + sg_miter_stop(sg_miter); + host->sg = NULL; smp_wmb(); @@ -1435,12 +1432,20 @@ static void dw_mci_write_data_pio(struct dw_mci *host) return; } } while (status & SDMMC_INT_TXDR); /* if TXDR write again */ - host->pio_offset = offset; data->bytes_xfered += nbytes; + + if (!remain) { + if (!sg_miter_next(sg_miter)) + goto done; + sg_miter->consumed = 0; + } + sg_miter_stop(sg_miter); return; done: data->bytes_xfered += nbytes; + sg_miter_stop(sg_miter); + host->sg = NULL; smp_wmb(); set_bit(EVENT_XFER_COMPLETE, &host->pending_events); } @@ -1643,6 +1648,7 @@ static void dw_mci_work_routine_card(struct work_struct *work) * block interrupt, hence setting the * scatter-gather pointer to NULL. */ + sg_miter_stop(&host->sg_miter); host->sg = NULL; ctrl = mci_readl(host, CTRL); diff --git a/include/linux/mmc/dw_mmc.h b/include/linux/mmc/dw_mmc.h index e8779c6d1759..aae5d1f1bb39 100644 --- a/include/linux/mmc/dw_mmc.h +++ b/include/linux/mmc/dw_mmc.h @@ -14,6 +14,8 @@ #ifndef LINUX_MMC_DW_MMC_H #define LINUX_MMC_DW_MMC_H +#include + #define MAX_MCI_SLOTS 2 enum dw_mci_state { @@ -40,7 +42,7 @@ struct mmc_data; * @lock: Spinlock protecting the queue and associated data. * @regs: Pointer to MMIO registers. * @sg: Scatterlist entry currently being processed by PIO code, if any. - * @pio_offset: Offset into the current scatterlist entry. + * @sg_miter: PIO mapping scatterlist iterator. * @cur_slot: The slot which is currently using the controller. * @mrq: The request currently being processed on @cur_slot, * or NULL if the controller is idle. @@ -115,7 +117,7 @@ struct dw_mci { void __iomem *regs; struct scatterlist *sg; - unsigned int pio_offset; + struct sg_mapping_iter sg_miter; struct dw_mci_slot *cur_slot; struct mmc_request *mrq; -- cgit v1.2.3-59-g8ed1b From 40e8c738785a25be585fcf661c6bb32f1a090ef2 Mon Sep 17 00:00:00 2001 From: Dave Airlie Date: Mon, 13 Feb 2012 12:18:37 +0000 Subject: drm/radeon/kms: drop lock in return path of radeon_fence_count_emitted. Silly bad return path. Reported-and-Tested-by: Mikko Vinni Reviewed-by: Alex Deucher CC: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_fence.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_fence.c b/drivers/gpu/drm/radeon/radeon_fence.c index 64ea3dd9e6ff..4bd36a354fbe 100644 --- a/drivers/gpu/drm/radeon/radeon_fence.c +++ b/drivers/gpu/drm/radeon/radeon_fence.c @@ -364,8 +364,10 @@ int radeon_fence_count_emitted(struct radeon_device *rdev, int ring) int not_processed = 0; read_lock_irqsave(&rdev->fence_lock, irq_flags); - if (!rdev->fence_drv[ring].initialized) + if (!rdev->fence_drv[ring].initialized) { + read_unlock_irqrestore(&rdev->fence_lock, irq_flags); return 0; + } if (!list_empty(&rdev->fence_drv[ring].emitted)) { struct list_head *ptr; -- cgit v1.2.3-59-g8ed1b From 6f9f8a61089bb177e53e14ee62f4a65134f3692f Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 13 Feb 2012 08:59:41 -0500 Subject: drm/radeon/kms/atom: bios scratch reg handling updates - Add missing DFP6 connection state handling - crtc routing bits not used on DCE4+ Noticed by sylware on phoronix. Signed-off-by: Alex Deucher Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/radeon_atombios.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/radeon_atombios.c b/drivers/gpu/drm/radeon/radeon_atombios.c index 5082d17d14dc..9e72daeeddc6 100644 --- a/drivers/gpu/drm/radeon/radeon_atombios.c +++ b/drivers/gpu/drm/radeon/radeon_atombios.c @@ -2931,6 +2931,20 @@ radeon_atombios_connected_scratch_regs(struct drm_connector *connector, bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP5; } } + if ((radeon_encoder->devices & ATOM_DEVICE_DFP6_SUPPORT) && + (radeon_connector->devices & ATOM_DEVICE_DFP6_SUPPORT)) { + if (connected) { + DRM_DEBUG_KMS("DFP6 connected\n"); + bios_0_scratch |= ATOM_S0_DFP6; + bios_3_scratch |= ATOM_S3_DFP6_ACTIVE; + bios_6_scratch |= ATOM_S6_ACC_REQ_DFP6; + } else { + DRM_DEBUG_KMS("DFP6 disconnected\n"); + bios_0_scratch &= ~ATOM_S0_DFP6; + bios_3_scratch &= ~ATOM_S3_DFP6_ACTIVE; + bios_6_scratch &= ~ATOM_S6_ACC_REQ_DFP6; + } + } if (rdev->family >= CHIP_R600) { WREG32(R600_BIOS_0_SCRATCH, bios_0_scratch); @@ -2951,6 +2965,9 @@ radeon_atombios_encoder_crtc_scratch_regs(struct drm_encoder *encoder, int crtc) struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); uint32_t bios_3_scratch; + if (ASIC_IS_DCE4(rdev)) + return; + if (rdev->family >= CHIP_R600) bios_3_scratch = RREG32(R600_BIOS_3_SCRATCH); else -- cgit v1.2.3-59-g8ed1b From b7f5b7dec3d539a84734f2bcb7e53fbb1532a40b Mon Sep 17 00:00:00 2001 From: Alex Deucher Date: Mon, 13 Feb 2012 16:36:34 -0500 Subject: drm/radeon/kms: fix MSI re-arm on rv370+ MSI_REARM_EN register is a write only trigger register. There is no need RMW when re-arming. May fix: https://bugs.freedesktop.org/show_bug.cgi?id=41668 Signed-off-by: Alex Deucher CC: stable@vger.kernel.org Signed-off-by: Dave Airlie --- drivers/gpu/drm/radeon/r100.c | 4 +--- drivers/gpu/drm/radeon/rs600.c | 4 +--- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bfd36ab643a6..18cd84fae99c 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -789,9 +789,7 @@ int r100_irq_process(struct radeon_device *rdev) WREG32(RADEON_AIC_CNTL, msi_rearm | RS400_MSI_REARM); break; default: - msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; - WREG32(RADEON_MSI_REARM_EN, msi_rearm); - WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); + WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); break; } } diff --git a/drivers/gpu/drm/radeon/rs600.c b/drivers/gpu/drm/radeon/rs600.c index ec46eb45e34c..c05865e5521f 100644 --- a/drivers/gpu/drm/radeon/rs600.c +++ b/drivers/gpu/drm/radeon/rs600.c @@ -684,9 +684,7 @@ int rs600_irq_process(struct radeon_device *rdev) WREG32(RADEON_BUS_CNTL, msi_rearm | RS600_MSI_REARM); break; default: - msi_rearm = RREG32(RADEON_MSI_REARM_EN) & ~RV370_MSI_REARM_EN; - WREG32(RADEON_MSI_REARM_EN, msi_rearm); - WREG32(RADEON_MSI_REARM_EN, msi_rearm | RV370_MSI_REARM_EN); + WREG32(RADEON_MSI_REARM_EN, RV370_MSI_REARM_EN); break; } } -- cgit v1.2.3-59-g8ed1b From fc543637525b59af38af2ce09a4dbdd7d5eb27bf Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Tue, 14 Feb 2012 09:05:46 +0000 Subject: bnx2x: remove the 'poll' module option 'poll' was a debugging option, but turning it on these days leads to kernel panic. Remove it. Signed-off-by: Michal Schmidt Signed-off-by: David S. Miller --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 1e3f978ee6da..254521319150 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -117,10 +117,6 @@ static int dropless_fc; module_param(dropless_fc, int, 0); MODULE_PARM_DESC(dropless_fc, " Pause on exhausted host ring"); -static int poll; -module_param(poll, int, 0); -MODULE_PARM_DESC(poll, " Use polling (for debug)"); - static int mrrs = -1; module_param(mrrs, int, 0); MODULE_PARM_DESC(mrrs, " Force Max Read Req Size (0..3) (for debug)"); @@ -4834,20 +4830,11 @@ void bnx2x_drv_pulse(struct bnx2x *bp) static void bnx2x_timer(unsigned long data) { - u8 cos; struct bnx2x *bp = (struct bnx2x *) data; if (!netif_running(bp->dev)) return; - if (poll) { - struct bnx2x_fastpath *fp = &bp->fp[0]; - - for_each_cos_in_tx_queue(fp, cos) - bnx2x_tx_int(bp, &fp->txdata[cos]); - bnx2x_rx_int(fp, 1000); - } - if (!BP_NOMCP(bp)) { int mb_idx = BP_FW_MB_IDX(bp); u32 drv_pulse; @@ -10063,7 +10050,6 @@ static void __devinit bnx2x_set_modes_bitmap(struct bnx2x *bp) static int __devinit bnx2x_init_bp(struct bnx2x *bp) { int func; - int timer_interval; int rc; mutex_init(&bp->port.phy_mutex); @@ -10139,8 +10125,7 @@ static int __devinit bnx2x_init_bp(struct bnx2x *bp) bp->tx_ticks = (50 / BNX2X_BTR) * BNX2X_BTR; bp->rx_ticks = (25 / BNX2X_BTR) * BNX2X_BTR; - timer_interval = (CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ); - bp->current_interval = (poll ? poll : timer_interval); + bp->current_interval = CHIP_REV_IS_SLOW(bp) ? 5*HZ : HZ; init_timer(&bp->timer); bp->timer.expires = jiffies + bp->current_interval; -- cgit v1.2.3-59-g8ed1b From 3013dc0cceb9baaf25d5624034eeaa259bf99004 Mon Sep 17 00:00:00 2001 From: Eric Dumazet Date: Tue, 14 Feb 2012 10:27:09 +0000 Subject: 3c59x: shorten timer period for slave devices Jean Delvare reported bonding on top of 3c59x adapters was not detecting network cable removal fast enough. 3c59x indeed uses a 60 seconds timer to check link status if carrier is on, and 5 seconds if carrier is off. This patch reduces timer period to 5 seconds if device is a bonding slave. Reported-by: Jean Delvare Acked-by: Jean Delvare Acked-by: Steffen Klassert Signed-off-by: Eric Dumazet Signed-off-by: David S. Miller --- drivers/net/ethernet/3com/3c59x.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c index 8153a3e0a1a4..f9b74c0a8492 100644 --- a/drivers/net/ethernet/3com/3c59x.c +++ b/drivers/net/ethernet/3com/3c59x.c @@ -1842,7 +1842,7 @@ vortex_timer(unsigned long data) ok = 1; } - if (!netif_carrier_ok(dev)) + if (dev->flags & IFF_SLAVE || !netif_carrier_ok(dev)) next_tick = 5*HZ; if (vp->medialock) -- cgit v1.2.3-59-g8ed1b From 61cddc57dc14a5dffa0921d9a24fd68edbb374ac Mon Sep 17 00:00:00 2001 From: Lars-Peter Clausen Date: Wed, 15 Feb 2012 10:23:25 +0100 Subject: regmap: Fix cache defaults initialization from raw cache defaults Currently registers with a value of 0 are ignored when initializing the register defaults from raw defaults. This worked in the past, because registers without a explicit default were assumed to have a default value of 0. This was changed in commit b03622a8 ("regmap: Ensure rbtree syncs registers set to zero properly"). As a result registers, which have a raw default value of 0 are now assumed to have no default. This again can result in unnecessary writes when syncing the cache. It will also result in unnecessary reads for e.g. the first update operation. In the case where readback is not possible this will even let the update operation fail, if the register has not been written to before. So this patch removes the check. Instead it adds a check to ignore raw defaults for registers which are volatile, since those registers are not cached. Signed-off-by: Lars-Peter Clausen Signed-off-by: Mark Brown Cc: stable@vger.kernel.org --- drivers/base/regmap/regcache.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/base/regmap/regcache.c b/drivers/base/regmap/regcache.c index 1ead66186b7c..d1daa5e9fadf 100644 --- a/drivers/base/regmap/regcache.c +++ b/drivers/base/regmap/regcache.c @@ -53,7 +53,7 @@ static int regcache_hw_init(struct regmap *map) for (count = 0, i = 0; i < map->num_reg_defaults_raw; i++) { val = regcache_get_val(map->reg_defaults_raw, i, map->cache_word_size); - if (!val) + if (regmap_volatile(map, i)) continue; count++; } @@ -70,7 +70,7 @@ static int regcache_hw_init(struct regmap *map) for (i = 0, j = 0; i < map->num_reg_defaults_raw; i++) { val = regcache_get_val(map->reg_defaults_raw, i, map->cache_word_size); - if (!val) + if (regmap_volatile(map, i)) continue; map->reg_defaults[j].reg = i; map->reg_defaults[j].def = val; -- cgit v1.2.3-59-g8ed1b From 75c6062cb797afe624d65c955eb867035622e782 Mon Sep 17 00:00:00 2001 From: Eugenia Emantayev Date: Wed, 15 Feb 2012 06:22:49 +0000 Subject: mlx4: fix buffer overrun When passing MLX4_UC_STEER=1 it was translated to value 2 after mlx4_QP_ATTACH_wrapper. Therefore in new_steering_entry() unicast steer entries were added to index 2 of array of size 2. Fixing this bug by shift right to one position. Signed-off-by: Eugenia Emantayev Reviewed-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index dcd819bfb2f0..1420dbc947c2 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -2538,7 +2538,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, int attach = vhcr->op_modifier; int block_loopback = vhcr->in_modifier >> 31; u8 steer_type_mask = 2; - enum mlx4_steer_type type = gid[7] & steer_type_mask; + enum mlx4_steer_type type = (gid[7] & steer_type_mask) >> 1; qpn = vhcr->in_modifier & 0xffffff; err = get_res(dev, slave, qpn, RES_QP, &rqp); -- cgit v1.2.3-59-g8ed1b From 2531188b476c83fe29b1d3498a76e329f4b6f16b Mon Sep 17 00:00:00 2001 From: Eugenia Emantayev Date: Wed, 15 Feb 2012 06:22:57 +0000 Subject: mlx4: fix QP tree trashing When adding new unicast steer entry, before moving qp to state ready, actually before calling mlx4_RST2INIT_QP_wrapper(), there were added a lot of entries with local_qpn=0 into radix tree. This fact impacted the get_res() function and proper functioning of resource tracker in addition to adding trash entries into radix tree. Signed-off-by: Eugenia Emantayev Reviewed-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 1420dbc947c2..629cc3018746 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -374,6 +374,7 @@ static struct res_common *alloc_qp_tr(int id) ret->com.res_id = id; ret->com.state = RES_QP_RESERVED; + ret->local_qpn = id; INIT_LIST_HEAD(&ret->mcg_list); spin_lock_init(&ret->mcg_spl); -- cgit v1.2.3-59-g8ed1b From 9f5b6c632eb3b495d5ae701c43e67da930b1f637 Mon Sep 17 00:00:00 2001 From: Eugenia Emantayev Date: Wed, 15 Feb 2012 06:23:16 +0000 Subject: mlx4: add unicast steering entries to resource_tracker Add unicast steering entries to resource tracker. Do qp_detach also for these entries when VF doesn't shut down gracefully. Otherwise there is leakage of these resources, since they are not tracked. Signed-off-by: Eugenia Emantayev Reviewed-by: Yevgeny Petrilin Signed-off-by: David S. Miller --- drivers/net/ethernet/mellanox/mlx4/resource_tracker.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c index 629cc3018746..bfdb7af19e49 100644 --- a/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c +++ b/drivers/net/ethernet/mellanox/mlx4/resource_tracker.c @@ -73,6 +73,7 @@ struct res_gid { struct list_head list; u8 gid[16]; enum mlx4_protocol prot; + enum mlx4_steer_type steer; }; enum res_qp_states { @@ -2480,7 +2481,8 @@ static struct res_gid *find_gid(struct mlx4_dev *dev, int slave, } static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, - u8 *gid, enum mlx4_protocol prot) + u8 *gid, enum mlx4_protocol prot, + enum mlx4_steer_type steer) { struct res_gid *res; int err; @@ -2496,6 +2498,7 @@ static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, } else { memcpy(res->gid, gid, 16); res->prot = prot; + res->steer = steer; list_add_tail(&res->list, &rqp->mcg_list); err = 0; } @@ -2505,14 +2508,15 @@ static int add_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, } static int rem_mcg_res(struct mlx4_dev *dev, int slave, struct res_qp *rqp, - u8 *gid, enum mlx4_protocol prot) + u8 *gid, enum mlx4_protocol prot, + enum mlx4_steer_type steer) { struct res_gid *res; int err; spin_lock_irq(&rqp->mcg_spl); res = find_gid(dev, slave, rqp, gid); - if (!res || res->prot != prot) + if (!res || res->prot != prot || res->steer != steer) err = -EINVAL; else { list_del(&res->list); @@ -2548,7 +2552,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, qp.qpn = qpn; if (attach) { - err = add_mcg_res(dev, slave, rqp, gid, prot); + err = add_mcg_res(dev, slave, rqp, gid, prot, type); if (err) goto ex_put; @@ -2557,7 +2561,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, if (err) goto ex_rem; } else { - err = rem_mcg_res(dev, slave, rqp, gid, prot); + err = rem_mcg_res(dev, slave, rqp, gid, prot, type); if (err) goto ex_put; err = mlx4_qp_detach_common(dev, &qp, gid, prot, type); @@ -2568,7 +2572,7 @@ int mlx4_QP_ATTACH_wrapper(struct mlx4_dev *dev, int slave, ex_rem: /* ignore error return below, already in error */ - err1 = rem_mcg_res(dev, slave, rqp, gid, prot); + err1 = rem_mcg_res(dev, slave, rqp, gid, prot, type); ex_put: put_res(dev, slave, qpn, RES_QP); @@ -2607,7 +2611,7 @@ static void detach_qp(struct mlx4_dev *dev, int slave, struct res_qp *rqp) list_for_each_entry_safe(rgid, tmp, &rqp->mcg_list, list) { qp.qpn = rqp->local_qpn; err = mlx4_qp_detach_common(dev, &qp, rgid->gid, rgid->prot, - MLX4_MC_STEER); + rgid->steer); list_del(&rgid->list); kfree(rgid); } -- cgit v1.2.3-59-g8ed1b From 72ba009b8a159e995e40d3b4e5d7d265acead983 Mon Sep 17 00:00:00 2001 From: Tim Gardner Date: Wed, 15 Feb 2012 07:50:15 +0000 Subject: ipheth: Add iPhone 4S BugLink: http://bugs.launchpad.net/bugs/900802 Cc: stable@vger.kernel.org 3.2+ Signed-off-by: Till Kamppeter Signed-off-by: Tim Gardner Signed-off-by: David S. Miller --- drivers/net/usb/ipheth.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/net/usb/ipheth.c b/drivers/net/usb/ipheth.c index e84662db51cc..dd78c4cbd459 100644 --- a/drivers/net/usb/ipheth.c +++ b/drivers/net/usb/ipheth.c @@ -60,6 +60,7 @@ #define USB_PRODUCT_IPHONE_3GS 0x1294 #define USB_PRODUCT_IPHONE_4 0x1297 #define USB_PRODUCT_IPHONE_4_VZW 0x129c +#define USB_PRODUCT_IPHONE_4S 0x12a0 #define IPHETH_USBINTF_CLASS 255 #define IPHETH_USBINTF_SUBCLASS 253 @@ -103,6 +104,10 @@ static struct usb_device_id ipheth_table[] = { USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4_VZW, IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, IPHETH_USBINTF_PROTO) }, + { USB_DEVICE_AND_INTERFACE_INFO( + USB_VENDOR_APPLE, USB_PRODUCT_IPHONE_4S, + IPHETH_USBINTF_CLASS, IPHETH_USBINTF_SUBCLASS, + IPHETH_USBINTF_PROTO) }, { } }; MODULE_DEVICE_TABLE(usb, ipheth_table); -- cgit v1.2.3-59-g8ed1b From 1cc5a735185a963ed9324a65e1f2db02bf52c0d4 Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 15 Feb 2012 00:10:37 +0000 Subject: stmmac: do not discard frame on dribbling bit assert If this bit is set and the CRC error is reset, then the packet is valid. Only report this as stat info. Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/common.h | 1 + drivers/net/ethernet/stmicro/stmmac/enh_desc.c | 2 +- drivers/net/ethernet/stmicro/stmmac/norm_desc.c | 2 +- drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c | 7 ++++++- 4 files changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index d0b814ef0675..0319d640f728 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -67,6 +67,7 @@ struct stmmac_extra_stats { unsigned long ipc_csum_error; unsigned long rx_collision; unsigned long rx_crc; + unsigned long dribbling_bit; unsigned long rx_length; unsigned long rx_mii; unsigned long rx_multicast; diff --git a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c index d87976364ec5..ad1b627f8ec2 100644 --- a/drivers/net/ethernet/stmicro/stmmac/enh_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/enh_desc.c @@ -201,7 +201,7 @@ static int enh_desc_get_rx_status(void *data, struct stmmac_extra_stats *x, if (unlikely(p->des01.erx.dribbling)) { CHIP_DBG(KERN_ERR "GMAC RX: dribbling error\n"); - ret = discard_frame; + x->dribbling_bit++; } if (unlikely(p->des01.erx.sa_filter_fail)) { CHIP_DBG(KERN_ERR "GMAC RX : Source Address filter fail\n"); diff --git a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c index fda5d2b31d3a..25953bb45a73 100644 --- a/drivers/net/ethernet/stmicro/stmmac/norm_desc.c +++ b/drivers/net/ethernet/stmicro/stmmac/norm_desc.c @@ -104,7 +104,7 @@ static int ndesc_get_rx_status(void *data, struct stmmac_extra_stats *x, ret = discard_frame; } if (unlikely(p->des01.rx.dribbling)) - ret = discard_frame; + x->dribbling_bit++; if (unlikely(p->des01.rx.length_error)) { x->rx_length++; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index 9573303a706b..f98e1511660f 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -47,23 +47,25 @@ struct stmmac_stats { offsetof(struct stmmac_priv, xstats.m)} static const struct stmmac_stats stmmac_gstrings_stats[] = { + /* Transmit errors */ STMMAC_STAT(tx_underflow), STMMAC_STAT(tx_carrier), STMMAC_STAT(tx_losscarrier), STMMAC_STAT(vlan_tag), STMMAC_STAT(tx_deferred), STMMAC_STAT(tx_vlan), - STMMAC_STAT(rx_vlan), STMMAC_STAT(tx_jabber), STMMAC_STAT(tx_frame_flushed), STMMAC_STAT(tx_payload_error), STMMAC_STAT(tx_ip_header_error), + /* Receive errors */ STMMAC_STAT(rx_desc), STMMAC_STAT(sa_filter_fail), STMMAC_STAT(overflow_error), STMMAC_STAT(ipc_csum_error), STMMAC_STAT(rx_collision), STMMAC_STAT(rx_crc), + STMMAC_STAT(dribbling_bit), STMMAC_STAT(rx_length), STMMAC_STAT(rx_mii), STMMAC_STAT(rx_multicast), @@ -73,6 +75,8 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { STMMAC_STAT(sa_rx_filter_fail), STMMAC_STAT(rx_missed_cntr), STMMAC_STAT(rx_overflow_cntr), + STMMAC_STAT(rx_vlan), + /* Tx/Rx IRQ errors */ STMMAC_STAT(tx_undeflow_irq), STMMAC_STAT(tx_process_stopped_irq), STMMAC_STAT(tx_jabber_irq), @@ -82,6 +86,7 @@ static const struct stmmac_stats stmmac_gstrings_stats[] = { STMMAC_STAT(rx_watchdog_irq), STMMAC_STAT(tx_early_irq), STMMAC_STAT(fatal_bus_error_irq), + /* Extra info */ STMMAC_STAT(threshold), STMMAC_STAT(tx_pkt_n), STMMAC_STAT(rx_pkt_n), -- cgit v1.2.3-59-g8ed1b From 7a13f8f5b63652c035147aab5fcba7ee9101f1fb Mon Sep 17 00:00:00 2001 From: Francesco Virlinzi Date: Wed, 15 Feb 2012 00:10:38 +0000 Subject: stmmac: request_irq when use an ext wake irq line (v2) In case of we use an external Wake-Up IRQ line (priv->wol_irq != dev->irq) we need to invoke the request_irq. Signed-off-by: Francesco Virlinzi Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 96fa2da30763..970a3f415244 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1047,6 +1047,17 @@ static int stmmac_open(struct net_device *dev) goto open_error; } + /* Request the Wake IRQ in case of another line is used for WoL */ + if (priv->wol_irq != dev->irq) { + ret = request_irq(priv->wol_irq, stmmac_interrupt, + IRQF_SHARED, dev->name, dev); + if (unlikely(ret < 0)) { + pr_err("%s: ERROR: allocating the ext WoL IRQ %d " + "(error: %d)\n", __func__, priv->wol_irq, ret); + goto open_error_wolirq; + } + } + /* Enable the MAC Rx/Tx */ stmmac_set_mac(priv->ioaddr, true); @@ -1087,6 +1098,9 @@ static int stmmac_open(struct net_device *dev) return 0; +open_error_wolirq: + free_irq(dev->irq, dev); + open_error: #ifdef CONFIG_STMMAC_TIMER kfree(priv->tm); @@ -1127,6 +1141,8 @@ static int stmmac_release(struct net_device *dev) /* Free the IRQ lines */ free_irq(dev->irq, dev); + if (priv->wol_irq != dev->irq) + free_irq(priv->wol_irq, dev); /* Stop TX/RX DMA and clear the descriptors */ priv->hw->dma->stop_tx(priv->ioaddr); -- cgit v1.2.3-59-g8ed1b From cf3f047b9af49d4ee8abfa31b0ef0e99cbcaf17d Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 15 Feb 2012 00:10:39 +0000 Subject: stmmac: move hw init in the probe (v2) This patch moves the MAC HW initialization and the HW feature verification from the open to the probe function as D. Miller suggested. So the patch actually reorganizes and tidies-up some parts of the driver and indeed fixes some problem when tune its HW features. These can be overwritten by looking at the HW cap register at run-time and that generated problems. Signed-off-by: Giuseppe Cavallaro Reviewed-by: Francesco Virlinzi Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 3 +- drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 189 ++++++++++----------- drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 6 +- .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 23 ++- 4 files changed, 105 insertions(+), 116 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 120740020e2c..6ca2aa3cc43b 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -97,4 +97,5 @@ int stmmac_resume(struct net_device *ndev); int stmmac_suspend(struct net_device *ndev); int stmmac_dvr_remove(struct net_device *ndev); struct stmmac_priv *stmmac_dvr_probe(struct device *device, - struct plat_stmmacenet_data *plat_dat); + struct plat_stmmacenet_data *plat_dat, + void __iomem *addr); diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 970a3f415244..6ee593a55a64 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -241,7 +241,7 @@ static void stmmac_adjust_link(struct net_device *dev) case 1000: if (likely(priv->plat->has_gmac)) ctrl &= ~priv->hw->link.port; - stmmac_hw_fix_mac_speed(priv); + stmmac_hw_fix_mac_speed(priv); break; case 100: case 10: @@ -785,7 +785,7 @@ static u32 stmmac_get_synopsys_id(struct stmmac_priv *priv) u32 uid = ((hwid & 0x0000ff00) >> 8); u32 synid = (hwid & 0x000000ff); - pr_info("STMMAC - user ID: 0x%x, Synopsys ID: 0x%x\n", + pr_info("stmmac - user ID: 0x%x, Synopsys ID: 0x%x\n", uid, synid); return synid; @@ -869,38 +869,6 @@ static int stmmac_get_hw_features(struct stmmac_priv *priv) return hw_cap; } -/** - * stmmac_mac_device_setup - * @dev : device pointer - * Description: this is to attach the GMAC or MAC 10/100 - * main core structures that will be completed during the - * open step. - */ -static int stmmac_mac_device_setup(struct net_device *dev) -{ - struct stmmac_priv *priv = netdev_priv(dev); - - struct mac_device_info *device; - - if (priv->plat->has_gmac) - device = dwmac1000_setup(priv->ioaddr); - else - device = dwmac100_setup(priv->ioaddr); - - if (!device) - return -ENOMEM; - - priv->hw = device; - priv->hw->ring = &ring_mode_ops; - - if (device_can_wakeup(priv->device)) { - priv->wolopts = WAKE_MAGIC; /* Magic Frame as default */ - enable_irq_wake(priv->wol_irq); - } - - return 0; -} - static void stmmac_check_ether_addr(struct stmmac_priv *priv) { /* verify if the MAC address is valid, in case of failures it @@ -930,20 +898,8 @@ static int stmmac_open(struct net_device *dev) struct stmmac_priv *priv = netdev_priv(dev); int ret; - /* MAC HW device setup */ - ret = stmmac_mac_device_setup(dev); - if (ret < 0) - return ret; - stmmac_check_ether_addr(priv); - stmmac_verify_args(); - - /* Override with kernel parameters if supplied XXX CRS XXX - * this needs to have multiple instances */ - if ((phyaddr >= 0) && (phyaddr <= 31)) - priv->plat->phy_addr = phyaddr; - /* MDIO bus Registration */ ret = stmmac_mdio_register(dev); if (ret < 0) { @@ -976,44 +932,6 @@ static int stmmac_open(struct net_device *dev) goto open_error; } - stmmac_get_synopsys_id(priv); - - priv->hw_cap_support = stmmac_get_hw_features(priv); - - if (priv->hw_cap_support) { - pr_info(" Support DMA HW capability register"); - - /* We can override some gmac/dma configuration fields: e.g. - * enh_desc, tx_coe (e.g. that are passed through the - * platform) with the values from the HW capability - * register (if supported). - */ - priv->plat->enh_desc = priv->dma_cap.enh_desc; - priv->plat->tx_coe = priv->dma_cap.tx_coe; - priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; - - /* By default disable wol on magic frame if not supported */ - if (!priv->dma_cap.pmt_magic_frame) - priv->wolopts &= ~WAKE_MAGIC; - - } else - pr_info(" No HW DMA feature register supported"); - - /* Select the enhnaced/normal descriptor structures */ - stmmac_selec_desc_mode(priv); - - /* PMT module is not integrated in all the MAC devices. */ - if (priv->plat->pmt) { - pr_info(" Remote wake-up capable\n"); - device_set_wakeup_capable(priv->device, 1); - } - - priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); - if (priv->rx_coe) - pr_info(" Checksum Offload Engine supported\n"); - if (priv->plat->tx_coe) - pr_info(" Checksum insertion supported\n"); - /* Create and initialize the TX/RX descriptors chains. */ priv->dma_tx_size = STMMAC_ALIGN(dma_txsize); priv->dma_rx_size = STMMAC_ALIGN(dma_rxsize); @@ -1030,14 +948,14 @@ static int stmmac_open(struct net_device *dev) /* Copy the MAC addr into the HW */ priv->hw->mac->set_umac_addr(priv->ioaddr, dev->dev_addr, 0); + /* If required, perform hw setup of the bus. */ if (priv->plat->bus_setup) priv->plat->bus_setup(priv->ioaddr); + /* Initialize the MAC Core */ priv->hw->mac->core_init(priv->ioaddr); - netdev_update_features(dev); - /* Request the IRQ lines */ ret = request_irq(dev->irq, stmmac_interrupt, IRQF_SHARED, dev->name, dev); @@ -1073,7 +991,7 @@ static int stmmac_open(struct net_device *dev) #ifdef CONFIG_STMMAC_DEBUG_FS ret = stmmac_init_fs(dev); if (ret < 0) - pr_warning("\tFailed debugFS registration"); + pr_warning("%s: failed debugFS registration\n", __func__); #endif /* Start the ball rolling... */ DBG(probe, DEBUG, "%s: DMA RX/TX processes started...\n", dev->name); @@ -1083,6 +1001,7 @@ static int stmmac_open(struct net_device *dev) #ifdef CONFIG_STMMAC_TIMER priv->tm->timer_start(tmrate); #endif + /* Dump DMA/MAC registers */ if (netif_msg_hw(priv)) { priv->hw->mac->dump_regs(priv->ioaddr); @@ -1804,6 +1723,69 @@ static const struct net_device_ops stmmac_netdev_ops = { .ndo_set_mac_address = eth_mac_addr, }; +/** + * stmmac_hw_init - Init the MAC device + * @priv : pointer to the private device structure. + * Description: this function detects which MAC device + * (GMAC/MAC10-100) has to attached, checks the HW capability + * (if supported) and sets the driver's features (for example + * to use the ring or chaine mode or support the normal/enh + * descriptor structure). + */ +static int stmmac_hw_init(struct stmmac_priv *priv) +{ + int ret = 0; + struct mac_device_info *mac; + + /* Identify the MAC HW device */ + if (priv->plat->has_gmac) + mac = dwmac1000_setup(priv->ioaddr); + else + mac = dwmac100_setup(priv->ioaddr); + if (!mac) + return -ENOMEM; + + priv->hw = mac; + + /* To use the chained or ring mode */ + priv->hw->ring = &ring_mode_ops; + + /* Get and dump the chip ID */ + stmmac_get_synopsys_id(priv); + + /* Get the HW capability (new GMAC newer than 3.50a) */ + priv->hw_cap_support = stmmac_get_hw_features(priv); + if (priv->hw_cap_support) { + pr_info(" DMA HW capability register supported"); + + /* We can override some gmac/dma configuration fields: e.g. + * enh_desc, tx_coe (e.g. that are passed through the + * platform) with the values from the HW capability + * register (if supported). + */ + priv->plat->enh_desc = priv->dma_cap.enh_desc; + priv->plat->tx_coe = priv->dma_cap.tx_coe; + priv->plat->pmt = priv->dma_cap.pmt_remote_wake_up; + } else + pr_info(" No HW DMA feature register supported"); + + /* Select the enhnaced/normal descriptor structures */ + stmmac_selec_desc_mode(priv); + + priv->rx_coe = priv->hw->mac->rx_coe(priv->ioaddr); + if (priv->rx_coe) + pr_info(" RX Checksum Offload Engine supported\n"); + if (priv->plat->tx_coe) + pr_info(" TX Checksum insertion supported\n"); + + if (priv->plat->pmt) { + pr_info(" Wake-Up On Lan supported\n"); + device_set_wakeup_capable(priv->device, 1); + } + + return ret; +} + /** * stmmac_dvr_probe * @device: device pointer @@ -1811,7 +1793,8 @@ static const struct net_device_ops stmmac_netdev_ops = { * call the alloc_etherdev, allocate the priv structure. */ struct stmmac_priv *stmmac_dvr_probe(struct device *device, - struct plat_stmmacenet_data *plat_dat) + struct plat_stmmacenet_data *plat_dat, + void __iomem *addr) { int ret = 0; struct net_device *ndev = NULL; @@ -1831,10 +1814,27 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ether_setup(ndev); - ndev->netdev_ops = &stmmac_netdev_ops; stmmac_set_ethtool_ops(ndev); + priv->pause = pause; + priv->plat = plat_dat; + priv->ioaddr = addr; + priv->dev->base_addr = (unsigned long)addr; + + /* Verify driver arguments */ + stmmac_verify_args(); - ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; + /* Override with kernel parameters if supplied XXX CRS XXX + * this needs to have multiple instances */ + if ((phyaddr >= 0) && (phyaddr <= 31)) + priv->plat->phy_addr = phyaddr; + + /* Init MAC and get the capabilities */ + stmmac_hw_init(priv); + + ndev->netdev_ops = &stmmac_netdev_ops; + + ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM | + NETIF_F_RXCSUM; ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; ndev->watchdog_timeo = msecs_to_jiffies(watchdog); #ifdef STMMAC_VLAN_TAG_USED @@ -1846,8 +1846,6 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, if (flow_ctrl) priv->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ - priv->pause = pause; - priv->plat = plat_dat; netif_napi_add(ndev, &priv->napi, stmmac_poll, 64); spin_lock_init(&priv->lock); @@ -1855,15 +1853,10 @@ struct stmmac_priv *stmmac_dvr_probe(struct device *device, ret = register_netdev(ndev); if (ret) { - pr_err("%s: ERROR %i registering the device\n", - __func__, ret); + pr_err("%s: ERROR %i registering the device\n", __func__, ret); goto error; } - DBG(probe, DEBUG, "%s: Scatter/Gather: %s - HW checksums: %s\n", - ndev->name, (ndev->features & NETIF_F_SG) ? "on" : "off", - (ndev->features & NETIF_F_IP_CSUM) ? "on" : "off"); - return priv; error: diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c index c796de9eed72..50ad5b80cfaf 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c @@ -96,13 +96,11 @@ static int __devinit stmmac_pci_probe(struct pci_dev *pdev, stmmac_default_data(); - priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat); + priv = stmmac_dvr_probe(&(pdev->dev), &plat_dat, addr); if (!priv) { - pr_err("%s: main drivr probe failed", __func__); + pr_err("%s: main driver probe failed", __func__); goto err_out; } - priv->ioaddr = addr; - priv->dev->base_addr = (unsigned long)addr; priv->dev->irq = pdev->irq; priv->wol_irq = pdev->irq; diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c index 1ac83243649a..3aad9810237c 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c @@ -59,16 +59,20 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) goto out_release_region; } plat_dat = pdev->dev.platform_data; - priv = stmmac_dvr_probe(&(pdev->dev), plat_dat); + + /* Custom initialisation (if needed)*/ + if (plat_dat->init) { + ret = plat_dat->init(pdev); + if (unlikely(ret)) + goto out_unmap; + } + + priv = stmmac_dvr_probe(&(pdev->dev), plat_dat, addr); if (!priv) { - pr_err("%s: main drivr probe failed", __func__); + pr_err("%s: main driver probe failed", __func__); goto out_unmap; } - priv->ioaddr = addr; - /* Set the I/O base addr */ - priv->dev->base_addr = (unsigned long)addr; - /* Get the MAC information */ priv->dev->irq = platform_get_irq_byname(pdev, "macirq"); if (priv->dev->irq == -ENXIO) { @@ -92,13 +96,6 @@ static int stmmac_pltfr_probe(struct platform_device *pdev) platform_set_drvdata(pdev, priv->dev); - /* Custom initialisation */ - if (priv->plat->init) { - ret = priv->plat->init(pdev); - if (unlikely(ret)) - goto out_unmap; - } - pr_debug("STMMAC platform driver registration completed"); return 0; -- cgit v1.2.3-59-g8ed1b From 78a5249fc9dc0f8c70221751dc79b6d918e5ee9a Mon Sep 17 00:00:00 2001 From: Giuseppe CAVALLARO Date: Wed, 15 Feb 2012 00:10:40 +0000 Subject: stmmac: update the driver version to Feb 2012 (v2) Signed-off-by: Giuseppe Cavallaro Signed-off-by: David S. Miller --- drivers/net/ethernet/stmicro/stmmac/stmmac.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac.h b/drivers/net/ethernet/stmicro/stmmac/stmmac.h index 6ca2aa3cc43b..b4b095fdcf29 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac.h +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac.h @@ -21,7 +21,7 @@ *******************************************************************************/ #define STMMAC_RESOURCE_NAME "stmmaceth" -#define DRV_MODULE_VERSION "Dec_2011" +#define DRV_MODULE_VERSION "Feb_2012" #include #include #include "common.h" -- cgit v1.2.3-59-g8ed1b From 237114384ab22c174ec4641e809f8e6cbcfce774 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Wed, 15 Feb 2012 04:09:46 +0000 Subject: veth: Enforce minimum size of VETH_INFO_PEER VETH_INFO_PEER carries struct ifinfomsg plus optional IFLA attributes. A minimal size of sizeof(struct ifinfomsg) must be enforced or we may risk accessing that struct beyond the limits of the netlink message. Signed-off-by: Thomas Graf Signed-off-by: David S. Miller --- drivers/net/veth.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 49f4667e1fa3..4a3402898f2a 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -422,7 +422,9 @@ static void veth_dellink(struct net_device *dev, struct list_head *head) unregister_netdevice_queue(peer, head); } -static const struct nla_policy veth_policy[VETH_INFO_MAX + 1]; +static const struct nla_policy veth_policy[VETH_INFO_MAX + 1] = { + [VETH_INFO_PEER] = { .len = sizeof(struct ifinfomsg) }, +}; static struct rtnl_link_ops veth_link_ops = { .kind = DRV_NAME, -- cgit v1.2.3-59-g8ed1b From 6c23e4132258be41218584cfb37a43d9346cdd64 Mon Sep 17 00:00:00 2001 From: Jan Weitzel Date: Tue, 14 Feb 2012 21:35:15 +0000 Subject: net/ethernet: ks8851_mll fix irq handling There a two different irq variables ks->irq and netdev->irq. Only ks->irq is set on probe, so disabling irq in ks_start_xmit fails. This patches remove ks->irq from private data and use only netdev->irq. Tested on a kernel 3.0 based OMAP4430 SMP Board Signed-off-by: Jan Weitzel Signed-off-by: David S. Miller --- drivers/net/ethernet/micrel/ks8851_mll.c | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/net/ethernet/micrel/ks8851_mll.c b/drivers/net/ethernet/micrel/ks8851_mll.c index e58e78e5c930..231176fcd2ba 100644 --- a/drivers/net/ethernet/micrel/ks8851_mll.c +++ b/drivers/net/ethernet/micrel/ks8851_mll.c @@ -394,7 +394,6 @@ union ks_tx_hdr { * @msg_enable : The message flags controlling driver output (see ethtool). * @frame_cnt : number of frames received. * @bus_width : i/o bus width. - * @irq : irq number assigned to this device. * @rc_rxqcr : Cached copy of KS_RXQCR. * @rc_txcr : Cached copy of KS_TXCR. * @rc_ier : Cached copy of KS_IER. @@ -441,7 +440,6 @@ struct ks_net { u32 msg_enable; u32 frame_cnt; int bus_width; - int irq; u16 rc_rxqcr; u16 rc_txcr; @@ -907,10 +905,10 @@ static int ks_net_open(struct net_device *netdev) netif_dbg(ks, ifup, ks->netdev, "%s - entry\n", __func__); /* reset the HW */ - err = request_irq(ks->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev); + err = request_irq(netdev->irq, ks_irq, KS_INT_FLAGS, DRV_NAME, netdev); if (err) { - pr_err("Failed to request IRQ: %d: %d\n", ks->irq, err); + pr_err("Failed to request IRQ: %d: %d\n", netdev->irq, err); return err; } @@ -955,7 +953,7 @@ static int ks_net_stop(struct net_device *netdev) /* set powermode to soft power down to save power */ ks_set_powermode(ks, PMECR_PM_SOFTDOWN); - free_irq(ks->irq, netdev); + free_irq(netdev->irq, netdev); mutex_unlock(&ks->lock); return 0; } @@ -1545,10 +1543,10 @@ static int __devinit ks8851_probe(struct platform_device *pdev) if (!ks->hw_addr_cmd) goto err_ioremap1; - ks->irq = platform_get_irq(pdev, 0); + netdev->irq = platform_get_irq(pdev, 0); - if (ks->irq < 0) { - err = ks->irq; + if (netdev->irq < 0) { + err = netdev->irq; goto err_get_irq; } -- cgit v1.2.3-59-g8ed1b From 64f8c13561fbd2f1a8b4a8975b2aee73b561093e Mon Sep 17 00:00:00 2001 From: majianpeng Date: Fri, 3 Feb 2012 14:35:59 +0000 Subject: powerpc/adb: Use set_current_state() Signed-off-by: majianpeng Signed-off-by: Benjamin Herrenschmidt --- drivers/macintosh/adb.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/macintosh/adb.c b/drivers/macintosh/adb.c index 75049e765191..b026896206ca 100644 --- a/drivers/macintosh/adb.c +++ b/drivers/macintosh/adb.c @@ -710,7 +710,7 @@ static ssize_t adb_read(struct file *file, char __user *buf, req = NULL; spin_lock_irqsave(&state->lock, flags); add_wait_queue(&state->wait_queue, &wait); - current->state = TASK_INTERRUPTIBLE; + set_current_state(TASK_INTERRUPTIBLE); for (;;) { req = state->completed; @@ -734,7 +734,7 @@ static ssize_t adb_read(struct file *file, char __user *buf, spin_lock_irqsave(&state->lock, flags); } - current->state = TASK_RUNNING; + set_current_state(TASK_RUNNING); remove_wait_queue(&state->wait_queue, &wait); spin_unlock_irqrestore(&state->lock, flags); -- cgit v1.2.3-59-g8ed1b