aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-04-20 12:21:19 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-04-20 12:21:19 -0400
commit27ee8963708185b96bc84a149eb5336a249a7497 (patch)
treea69f91f42522182b524fcb57f269da2cfcb3f52d /drivers
parentac8bf564307962a763a52b34e771205c58b76ec8 (diff)
parent07a71415d5f790385695784a9b0e554412ee95c3 (diff)
Merge branch 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
* 'urgent' of git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6: pcmcia: fix error handling in cm4000_cs.c drivers/pcmcia: Add missing local_irq_restore serial_cs: MD55x support (PCMCIA GPRS/EDGE modem) (kernel 2.6.33) pcmcia: avoid late calls to pccard_validate_cis pcmcia: fix ioport size calculation in rsrc_nonstatic pcmcia: re-start on MFC override pcmcia: fix io_probe due to parent (PCI) resources pcmcia: use previously assigned IRQ for all card functions
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c8
-rw-r--r--drivers/pcmcia/cistpl.c9
-rw-r--r--drivers/pcmcia/db1xxx_ss.c4
-rw-r--r--drivers/pcmcia/ds.c22
-rw-r--r--drivers/pcmcia/pcmcia_resource.c10
-rw-r--r--drivers/pcmcia/rsrc_nonstatic.c16
-rw-r--r--drivers/serial/serial_cs.c9
7 files changed, 55 insertions, 23 deletions
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index c9bc896d68af..90b199f97bec 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -1026,14 +1026,16 @@ static ssize_t cmm_read(struct file *filp, __user char *buf, size_t count,
1026 1026
1027 xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */ 1027 xoutb(0, REG_FLAGS1(iobase)); /* clear detectCMM */
1028 /* last check before exit */ 1028 /* last check before exit */
1029 if (!io_detect_cm4000(iobase, dev)) 1029 if (!io_detect_cm4000(iobase, dev)) {
1030 count = -ENODEV; 1030 rc = -ENODEV;
1031 goto release_io;
1032 }
1031 1033
1032 if (test_bit(IS_INVREV, &dev->flags) && count > 0) 1034 if (test_bit(IS_INVREV, &dev->flags) && count > 0)
1033 str_invert_revert(dev->rbuf, count); 1035 str_invert_revert(dev->rbuf, count);
1034 1036
1035 if (copy_to_user(buf, dev->rbuf, count)) 1037 if (copy_to_user(buf, dev->rbuf, count))
1036 return -EFAULT; 1038 rc = -EFAULT;
1037 1039
1038release_io: 1040release_io:
1039 clear_bit(LOCK_IO, &dev->flags); 1041 clear_bit(LOCK_IO, &dev->flags);
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index f230f6543bff..854959cada3a 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -1484,6 +1484,11 @@ int pccard_validate_cis(struct pcmcia_socket *s, unsigned int *info)
1484 if (!s) 1484 if (!s)
1485 return -EINVAL; 1485 return -EINVAL;
1486 1486
1487 if (s->functions) {
1488 WARN_ON(1);
1489 return -EINVAL;
1490 }
1491
1487 /* We do not want to validate the CIS cache... */ 1492 /* We do not want to validate the CIS cache... */
1488 mutex_lock(&s->ops_mutex); 1493 mutex_lock(&s->ops_mutex);
1489 destroy_cis_cache(s); 1494 destroy_cis_cache(s);
@@ -1639,7 +1644,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
1639 count = 0; 1644 count = 0;
1640 else { 1645 else {
1641 struct pcmcia_socket *s; 1646 struct pcmcia_socket *s;
1642 unsigned int chains; 1647 unsigned int chains = 1;
1643 1648
1644 if (off + count > size) 1649 if (off + count > size)
1645 count = size - off; 1650 count = size - off;
@@ -1648,7 +1653,7 @@ static ssize_t pccard_show_cis(struct kobject *kobj,
1648 1653
1649 if (!(s->state & SOCKET_PRESENT)) 1654 if (!(s->state & SOCKET_PRESENT))
1650 return -ENODEV; 1655 return -ENODEV;
1651 if (pccard_validate_cis(s, &chains)) 1656 if (!s->functions && pccard_validate_cis(s, &chains))
1652 return -EIO; 1657 return -EIO;
1653 if (!chains) 1658 if (!chains)
1654 return -ENODATA; 1659 return -ENODATA;
diff --git a/drivers/pcmcia/db1xxx_ss.c b/drivers/pcmcia/db1xxx_ss.c
index 6206408e196c..2d48196a48cd 100644
--- a/drivers/pcmcia/db1xxx_ss.c
+++ b/drivers/pcmcia/db1xxx_ss.c
@@ -166,8 +166,10 @@ static int db1x_pcmcia_setup_irqs(struct db1x_pcmcia_sock *sock)
166 166
167 ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq, 167 ret = request_irq(sock->insert_irq, db1200_pcmcia_cdirq,
168 IRQF_DISABLED, "pcmcia_insert", sock); 168 IRQF_DISABLED, "pcmcia_insert", sock);
169 if (ret) 169 if (ret) {
170 local_irq_restore(flags);
170 goto out1; 171 goto out1;
172 }
171 173
172 ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq, 174 ret = request_irq(sock->eject_irq, db1200_pcmcia_cdirq,
173 IRQF_DISABLED, "pcmcia_eject", sock); 175 IRQF_DISABLED, "pcmcia_eject", sock);
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index cb6036d89e59..4014cf8e4a26 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -687,12 +687,10 @@ static void pcmcia_requery(struct pcmcia_socket *s)
687 new_funcs = mfc.nfn; 687 new_funcs = mfc.nfn;
688 else 688 else
689 new_funcs = 1; 689 new_funcs = 1;
690 if (old_funcs > new_funcs) { 690 if (old_funcs != new_funcs) {
691 /* we need to re-start */
691 pcmcia_card_remove(s, NULL); 692 pcmcia_card_remove(s, NULL);
692 pcmcia_card_add(s); 693 pcmcia_card_add(s);
693 } else if (new_funcs > old_funcs) {
694 s->functions = new_funcs;
695 pcmcia_device_add(s, 1);
696 } 694 }
697 } 695 }
698 696
@@ -728,6 +726,8 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
728 struct pcmcia_socket *s = dev->socket; 726 struct pcmcia_socket *s = dev->socket;
729 const struct firmware *fw; 727 const struct firmware *fw;
730 int ret = -ENOMEM; 728 int ret = -ENOMEM;
729 cistpl_longlink_mfc_t mfc;
730 int old_funcs, new_funcs = 1;
731 731
732 if (!filename) 732 if (!filename)
733 return -EINVAL; 733 return -EINVAL;
@@ -750,6 +750,14 @@ static int pcmcia_load_firmware(struct pcmcia_device *dev, char * filename)
750 goto release; 750 goto release;
751 } 751 }
752 752
753 /* we need to re-start if the number of functions changed */
754 old_funcs = s->functions;
755 if (!pccard_read_tuple(s, BIND_FN_ALL, CISTPL_LONGLINK_MFC,
756 &mfc))
757 new_funcs = mfc.nfn;
758
759 if (old_funcs != new_funcs)
760 ret = -EBUSY;
753 761
754 /* update information */ 762 /* update information */
755 pcmcia_device_query(dev); 763 pcmcia_device_query(dev);
@@ -858,10 +866,8 @@ static inline int pcmcia_devmatch(struct pcmcia_device *dev,
858 if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) { 866 if (did->match_flags & PCMCIA_DEV_ID_MATCH_FAKE_CIS) {
859 dev_dbg(&dev->dev, "device needs a fake CIS\n"); 867 dev_dbg(&dev->dev, "device needs a fake CIS\n");
860 if (!dev->socket->fake_cis) 868 if (!dev->socket->fake_cis)
861 pcmcia_load_firmware(dev, did->cisfile); 869 if (pcmcia_load_firmware(dev, did->cisfile))
862 870 return 0;
863 if (!dev->socket->fake_cis)
864 return 0;
865 } 871 }
866 872
867 if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) { 873 if (did->match_flags & PCMCIA_DEV_ID_MATCH_ANONYMOUS) {
diff --git a/drivers/pcmcia/pcmcia_resource.c b/drivers/pcmcia/pcmcia_resource.c
index caec1dee2a4b..7c3d03bb4f30 100644
--- a/drivers/pcmcia/pcmcia_resource.c
+++ b/drivers/pcmcia/pcmcia_resource.c
@@ -755,12 +755,12 @@ int pcmcia_request_irq(struct pcmcia_device *p_dev, irq_req_t *req)
755 else 755 else
756 printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n"); 756 printk(KERN_WARNING "pcmcia: Driver needs updating to support IRQ sharing.\n");
757 757
758#ifdef CONFIG_PCMCIA_PROBE 758 /* If the interrupt is already assigned, it must be the same */
759 759 if (s->irq.AssignedIRQ != 0)
760 if (s->irq.AssignedIRQ != 0) {
761 /* If the interrupt is already assigned, it must be the same */
762 irq = s->irq.AssignedIRQ; 760 irq = s->irq.AssignedIRQ;
763 } else { 761
762#ifdef CONFIG_PCMCIA_PROBE
763 if (!irq) {
764 int try; 764 int try;
765 u32 mask = s->irq_mask; 765 u32 mask = s->irq_mask;
766 void *data = p_dev; /* something unique to this device */ 766 void *data = p_dev; /* something unique to this device */
diff --git a/drivers/pcmcia/rsrc_nonstatic.c b/drivers/pcmcia/rsrc_nonstatic.c
index 559069a80a3b..a6eb7b59ba9f 100644
--- a/drivers/pcmcia/rsrc_nonstatic.c
+++ b/drivers/pcmcia/rsrc_nonstatic.c
@@ -214,7 +214,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
214 return; 214 return;
215 } 215 }
216 for (i = base, most = 0; i < base+num; i += 8) { 216 for (i = base, most = 0; i < base+num; i += 8) {
217 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); 217 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
218 if (!res) 218 if (!res)
219 continue; 219 continue;
220 hole = inb(i); 220 hole = inb(i);
@@ -231,9 +231,14 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
231 231
232 bad = any = 0; 232 bad = any = 0;
233 for (i = base; i < base+num; i += 8) { 233 for (i = base; i < base+num; i += 8) {
234 res = claim_region(NULL, i, 8, IORESOURCE_IO, "PCMCIA ioprobe"); 234 res = claim_region(s, i, 8, IORESOURCE_IO, "PCMCIA ioprobe");
235 if (!res) 235 if (!res) {
236 if (!any)
237 printk(" excluding");
238 if (!bad)
239 bad = any = i;
236 continue; 240 continue;
241 }
237 for (j = 0; j < 8; j++) 242 for (j = 0; j < 8; j++)
238 if (inb(i+j) != most) 243 if (inb(i+j) != most)
239 break; 244 break;
@@ -253,6 +258,7 @@ static void do_io_probe(struct pcmcia_socket *s, unsigned int base,
253 } 258 }
254 if (bad) { 259 if (bad) {
255 if ((num > 16) && (bad == base) && (i == base+num)) { 260 if ((num > 16) && (bad == base) && (i == base+num)) {
261 sub_interval(&s_data->io_db, bad, i-bad);
256 printk(" nothing: probe failed.\n"); 262 printk(" nothing: probe failed.\n");
257 return; 263 return;
258 } else { 264 } else {
@@ -804,7 +810,7 @@ static int adjust_memory(struct pcmcia_socket *s, unsigned int action, unsigned
804static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end) 810static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long start, unsigned long end)
805{ 811{
806 struct socket_data *data = s->resource_data; 812 struct socket_data *data = s->resource_data;
807 unsigned long size = end - start + 1; 813 unsigned long size;
808 int ret = 0; 814 int ret = 0;
809 815
810#if defined(CONFIG_X86) 816#if defined(CONFIG_X86)
@@ -814,6 +820,8 @@ static int adjust_io(struct pcmcia_socket *s, unsigned int action, unsigned long
814 start = 0x100; 820 start = 0x100;
815#endif 821#endif
816 822
823 size = end - start + 1;
824
817 if (end < start) 825 if (end < start)
818 return -EINVAL; 826 return -EINVAL;
819 827
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 175d202ab37e..8cfa5b12ea7a 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -105,6 +105,10 @@ struct serial_cfg_mem {
105 * manfid 0x0160, 0x0104 105 * manfid 0x0160, 0x0104
106 * This card appears to have a 14.7456MHz clock. 106 * This card appears to have a 14.7456MHz clock.
107 */ 107 */
108/* Generic Modem: MD55x (GPRS/EDGE) have
109 * Elan VPU16551 UART with 14.7456MHz oscillator
110 * manfid 0x015D, 0x4C45
111 */
108static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port) 112static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
109{ 113{
110 port->uartclk = 14745600; 114 port->uartclk = 14745600;
@@ -196,6 +200,11 @@ static const struct serial_quirk quirks[] = {
196 .multi = -1, 200 .multi = -1,
197 .setup = quirk_setup_brainboxes_0104, 201 .setup = quirk_setup_brainboxes_0104,
198 }, { 202 }, {
203 .manfid = 0x015D,
204 .prodid = 0x4C45,
205 .multi = -1,
206 .setup = quirk_setup_brainboxes_0104,
207 }, {
199 .manfid = MANFID_IBM, 208 .manfid = MANFID_IBM,
200 .prodid = ~0, 209 .prodid = ~0,
201 .multi = -1, 210 .multi = -1,