static u8 ali_cable_detect(ide_hwif_t *hwif) { struct pci_dev *dev = to_pci_dev(hwif->dev); unsigned long flags; u8 cbl = ATA_CBL_PATA40, tmpbyte; local_irq_save_nort(flags); if (m5229_revision >= 0xC2) { /* * m5229 80-pin cable detection (from Host View) * * 0x4a bit0 is 0 => primary channel has 80-pin * 0x4a bit1 is 0 => secondary channel has 80-pin * * Certain laptops use short but suitable cables * and don't implement the detect logic. */ if (ali_cable_override(dev)) cbl = ATA_CBL_PATA40_SHORT; else { pci_read_config_byte(dev, 0x4a, &tmpbyte); if ((tmpbyte & (1 << hwif->channel)) == 0) cbl = ATA_CBL_PATA80; } } local_irq_restore_nort(flags); return cbl; }
/* * output trigger callback */ static void snd_mpu401_uart_output_trigger(snd_rawmidi_substream_t * substream, int up) { unsigned long flags; mpu401_t *mpu; mpu = substream->rmidi->private_data; if (up) { set_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); /* try to add the timer at each output trigger, * since the output timer might have been removed in * snd_mpu401_uart_output_write(). */ snd_mpu401_uart_add_timer(mpu, 0); /* output pending data */ /* prevent double enter via rawmidi->event callback */ if (atomic_dec_and_test(&mpu->tx_loop)) { local_irq_save_nort(flags); if (spin_trylock(&mpu->output_lock)) { snd_mpu401_uart_output_write(mpu); spin_unlock(&mpu->output_lock); } local_irq_restore_nort(flags); } atomic_inc(&mpu->tx_loop); } else { snd_mpu401_uart_remove_timer(mpu, 0); clear_bit(MPU401_MODE_BIT_OUTPUT_TRIGGER, &mpu->mode); } }
static int __res_counter_charge(struct res_counter *counter, unsigned long val, struct res_counter **limit_fail_at, bool force) { int ret, r; unsigned long flags; struct res_counter *c, *u; r = ret = 0; *limit_fail_at = NULL; local_irq_save_nort(flags); for (c = counter; c != NULL; c = c->parent) { spin_lock(&c->lock); r = res_counter_charge_locked(c, val, force); spin_unlock(&c->lock); if (r < 0 && !ret) { ret = r; *limit_fail_at = c; if (!force) break; } } if (ret < 0 && !force) { for (u = counter; u != c; u = u->parent) { spin_lock(&u->lock); res_counter_uncharge_locked(u, val); spin_unlock(&u->lock); } } local_irq_restore_nort(flags); return ret; }
/* * trigger input callback */ static void snd_mpu401_uart_input_trigger(snd_rawmidi_substream_t * substream, int up) { unsigned long flags; mpu401_t *mpu; int max = 64; mpu = substream->rmidi->private_data; if (up) { if (! test_and_set_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode)) { /* first time - flush FIFO */ while (max-- > 0) mpu->read(mpu, MPU401D(mpu)); if (mpu->irq < 0) snd_mpu401_uart_add_timer(mpu, 1); } /* read data in advance */ /* prevent double enter via rawmidi->event callback */ if (atomic_dec_and_test(&mpu->rx_loop)) { local_irq_save_nort(flags); if (spin_trylock(&mpu->input_lock)) { snd_mpu401_uart_input_read(mpu); spin_unlock(&mpu->input_lock); } local_irq_restore_nort(flags); } atomic_inc(&mpu->rx_loop); } else { if (mpu->irq < 0) snd_mpu401_uart_remove_timer(mpu, 1); clear_bit(MPU401_MODE_BIT_INPUT_TRIGGER, &mpu->mode); } }
int get_mailbox_data(struct audiodsp_priv *priv,int num,struct mail_msg *msg) { unsigned long flags; dma_addr_t buf_map; struct mail_msg *m; if(num>31 || num <0) return -1; local_irq_save_nort(flags); m=&priv->mailbox_reg[num]; pre_read_mailbox(m); //dsp_addr_map = dma_map_single(priv->dev,(void*)m,sizeof(*m),DMA_FROM_DEVICE); //dma_unmap_single(priv->dev,dsp_addr_map,sizeof(*m),DMA_FROM_DEVICE); msg->cmd=m->cmd; msg->data=m->data; msg->data = (char *)((unsigned)msg->data+AUDIO_DSP_START_ADDR); msg->status=m->status; msg->len=m->len; if(msg->len && msg->data != NULL){ buf_map = dma_map_single(priv->dev,(void*)msg->data ,msg->len,DMA_FROM_DEVICE); dma_unmap_single(priv->dev,buf_map,msg->len,DMA_FROM_DEVICE); } m->status=0; after_change_mailbox(m); local_irq_restore_nort(flags); return 0; }
int dsp_mailbox_send(struct audiodsp_priv *priv,int overwrite,int num,int cmd,const char *data,int len) { unsigned long flags; int res=-1; struct mail_msg *m; dma_addr_t buf_map; m=&priv->mailbox_reg2[num]; local_irq_save_nort(flags); if(overwrite || m->status==0) { m->cmd=cmd; m->data=(char *)ARM_2_ARC_ADDR_SWAP((unsigned)data); m->len=len; m->status=1; after_change_mailbox(m); if(data!=NULL && len >0) { buf_map = dma_map_single(NULL, (void *)data, len, DMA_TO_DEVICE); dma_unmap_single(NULL, buf_map, len, DMA_TO_DEVICE); } MAIBOX2_IRQ_ENABLE(num); DSP_TRIGGER_IRQ(num); res=0; } local_irq_restore_nort(flags); return res; }
void ide_pio_bytes(ide_drive_t *drive, struct ide_cmd *cmd, unsigned int write, unsigned int len) { ide_hwif_t *hwif = drive->hwif; struct scatterlist *sg = hwif->sg_table; struct scatterlist *cursg = cmd->cursg; struct page *page; unsigned long flags; unsigned int offset; u8 *buf; cursg = cmd->cursg; if (cursg == NULL) cursg = cmd->cursg = sg; while (len) { unsigned nr_bytes = min(len, cursg->length - cmd->cursg_ofs); if (nr_bytes > PAGE_SIZE) nr_bytes = PAGE_SIZE; page = sg_page(cursg); offset = cursg->offset + cmd->cursg_ofs; /* get the current page and offset */ page = nth_page(page, (offset >> PAGE_SHIFT)); offset %= PAGE_SIZE; if (PageHighMem(page)) local_irq_save_nort(flags); buf = kmap_atomic(page, KM_BIO_SRC_IRQ) + offset; cmd->nleft -= nr_bytes; cmd->cursg_ofs += nr_bytes; if (cmd->cursg_ofs == cursg->length) { cursg = cmd->cursg = sg_next(cmd->cursg); cmd->cursg_ofs = 0; } /* do the actual data transfer */ if (write) hwif->tp_ops->output_data(drive, cmd, buf, nr_bytes); else hwif->tp_ops->input_data(drive, cmd, buf, nr_bytes); kunmap_atomic(buf, KM_BIO_SRC_IRQ); if (PageHighMem(page)) local_irq_restore_nort(flags); len -= nr_bytes; } }
/* * highmem version, map in to vec */ static void bounce_copy_vec(struct bio_vec *to, unsigned char *vfrom) { unsigned long flags; unsigned char *vto; local_irq_save_nort(flags); vto = kmap_atomic(to->bv_page); memcpy(vto + to->bv_offset, vfrom, to->bv_len); kunmap_atomic(vto); local_irq_restore_nort(flags); }
void res_counter_uncharge_until(struct res_counter *counter, struct res_counter *top, unsigned long val) { unsigned long flags; struct res_counter *c; local_irq_save_nort(flags); for (c = counter; c != top; c = c->parent) { spin_lock(&c->lock); res_counter_uncharge_locked(c, val); spin_unlock(&c->lock); } local_irq_restore_nort(flags); }
static void ali_set_pio_mode(ide_drive_t *drive, const u8 pio) { ide_hwif_t *hwif = drive->hwif; struct pci_dev *dev = to_pci_dev(hwif->dev); struct ide_timing *t = ide_timing_find_mode(XFER_PIO_0 + pio); int s_time = t->setup, a_time = t->active, c_time = t->cycle; u8 s_clc, a_clc, r_clc; unsigned long flags; int bus_speed = ide_pci_clk ? ide_pci_clk : 33; int port = hwif->channel ? 0x5c : 0x58; int portFIFO = hwif->channel ? 0x55 : 0x54; u8 cd_dma_fifo = 0, unit = drive->dn & 1; if ((s_clc = (s_time * bus_speed + 999) / 1000) >= 8) s_clc = 0; if ((a_clc = (a_time * bus_speed + 999) / 1000) >= 8) a_clc = 0; if (!(r_clc = (c_time * bus_speed + 999) / 1000 - a_clc - s_clc)) { r_clc = 1; } else { if (r_clc >= 16) r_clc = 0; } local_irq_save_nort(flags); /* * PIO mode => ATA FIFO on, ATAPI FIFO off */ pci_read_config_byte(dev, portFIFO, &cd_dma_fifo); if (drive->media==ide_disk) { if (unit) { pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0x0F) | 0x50); } else { pci_write_config_byte(dev, portFIFO, (cd_dma_fifo & 0xF0) | 0x05); } } else { if (unit) { pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0x0F); } else { pci_write_config_byte(dev, portFIFO, cd_dma_fifo & 0xF0); } } pci_write_config_byte(dev, port, s_clc); pci_write_config_byte(dev, port + unit + 2, (a_clc << 4) | r_clc); local_irq_restore_nort(flags); }
/* * This is used for most PIO data transfers *to* the IDE interface */ void 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; unsigned long data_addr = io_ports->data_addr; unsigned int words = (len + 1) >> 1; u8 io_32bit = drive->io_32bit; u8 mmio = (hwif->host_flags & IDE_HFLAG_MMIO) ? 1 : 0; if (io_32bit) { unsigned long uninitialized_var(flags); if ((io_32bit & 2) && !mmio) { local_irq_save_nort(flags); ata_vlb_sync(io_ports->nsect_addr); } words >>= 1; if (mmio) __ide_mm_outsl((void __iomem *)data_addr, buf, words); else outsl(data_addr, buf, words); if ((io_32bit & 2) && !mmio) local_irq_restore_nort(flags); if (((len + 1) & 3) < 2) return; buf += len & ~3; words = 1; } if (mmio) __ide_mm_outsw((void __iomem *)data_addr, buf, words); else outsw(data_addr, buf, words); }
static int gameport_measure_speed(struct gameport *gameport) { #if defined(__i386__) unsigned int i, t, t1, t2, t3, tx; unsigned long flags; if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW)) return 0; tx = 1 << 30; for(i = 0; i < 50; i++) { local_irq_save_nort(flags); GET_TIME(t1); for (t = 0; t < 50; t++) gameport_read(gameport); GET_TIME(t2); GET_TIME(t3); local_irq_restore_nort(flags); udelay(i * 10); if ((t = DELTA(t2,t1) - DELTA(t3,t2)) < tx) tx = t; } gameport_close(gameport); return 59659 / (tx < 1 ? 1 : tx); #elif defined (__x86_64__) unsigned int i, t; unsigned long tx, t1, t2, flags; if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW)) return 0; tx = 1 << 30; for(i = 0; i < 50; i++) { local_irq_save_nort(flags); rdtscl(t1); for (t = 0; t < 50; t++) gameport_read(gameport); rdtscl(t2); local_irq_restore_nort(flags); udelay(i * 10); if (t2 - t1 < tx) tx = t2 - t1; } gameport_close(gameport); return (cpu_data(raw_smp_processor_id()).loops_per_jiffy * (unsigned long)HZ / (1000 / 50)) / (tx < 1 ? 1 : tx); #else unsigned int j, t = 0; if (gameport_open(gameport, NULL, GAMEPORT_MODE_RAW)) return 0; j = jiffies; while (j == jiffies); j = jiffies; while (j == jiffies) { t++; gameport_read(gameport); } gameport_close(gameport); return t * HZ / 1000; #endif }
static int init_chipset_ali15x3(struct pci_dev *dev) { unsigned long flags; u8 tmpbyte; struct pci_dev *north = pci_get_slot(dev->bus, PCI_DEVFN(0,0)); m5229_revision = dev->revision; isa_dev = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); local_irq_save_nort(flags); if (m5229_revision < 0xC2) { /* * revision 0x20 (1543-E, 1543-F) * revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E) * clear CD-ROM DMA write bit, m5229, 0x4b, bit 7 */ pci_read_config_byte(dev, 0x4b, &tmpbyte); /* * clear bit 7 */ pci_write_config_byte(dev, 0x4b, tmpbyte & 0x7F); /* * check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010 */ if (m5229_revision >= 0x20 && isa_dev) { pci_read_config_byte(isa_dev, 0x5e, &tmpbyte); chip_is_1543c_e = ((tmpbyte & 0x1e) == 0x12) ? 1: 0; } goto out; } /* * 1543C-B?, 1535, 1535D, 1553 * Note 1: not all "motherboard" support this detection * Note 2: if no udma 66 device, the detection may "error". * but in this case, we will not set the device to * ultra 66, the detection result is not important */ /* * enable "Cable Detection", m5229, 0x4b, bit3 */ pci_read_config_byte(dev, 0x4b, &tmpbyte); pci_write_config_byte(dev, 0x4b, tmpbyte | 0x08); /* * We should only tune the 1533 enable if we are using an ALi * North bridge. We might have no north found on some zany * box without a device at 0:0.0. The ALi bridge will be at * 0:0.0 so if we didn't find one we know what is cooking. */ if (north && north->vendor != PCI_VENDOR_ID_AL) goto out; if (m5229_revision < 0xC5 && isa_dev) { /* * set south-bridge's enable bit, m1533, 0x79 */ pci_read_config_byte(isa_dev, 0x79, &tmpbyte); if (m5229_revision == 0xC2) { /* * 1543C-B0 (m1533, 0x79, bit 2) */ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x04); } else if (m5229_revision >= 0xC3) { /* * 1553/1535 (m1533, 0x79, bit 1) */ pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02); } } out: /* * CD_ROM DMA on (m5229, 0x53, bit0) * Enable this bit even if we want to use PIO. * PIO FIFO off (m5229, 0x53, bit1) * The hardware will use 0x54h and 0x55h to control PIO FIFO. * (Not on later devices it seems) * * 0x53 changes meaning on later revs - we must no touch * bit 1 on them. Need to check if 0x20 is the right break. */ if (m5229_revision >= 0x20) { pci_read_config_byte(dev, 0x53, &tmpbyte); if (m5229_revision <= 0x20) tmpbyte = (tmpbyte & (~0x02)) | 0x01; else if (m5229_revision == 0xc7 || m5229_revision == 0xc8) tmpbyte |= 0x03; else tmpbyte |= 0x01; pci_write_config_byte(dev, 0x53, tmpbyte); } pci_dev_put(north); pci_dev_put(isa_dev); local_irq_restore_nort(flags); return 0; }