diff options
Diffstat (limited to 'drivers')
221 files changed, 4051 insertions, 1209 deletions
diff --git a/drivers/acpi/acpi_ipmi.c b/drivers/acpi/acpi_ipmi.c index f77956c3fd45..747c2ba98534 100644 --- a/drivers/acpi/acpi_ipmi.c +++ b/drivers/acpi/acpi_ipmi.c @@ -56,7 +56,7 @@ struct acpi_ipmi_device { struct ipmi_driver_data { struct list_head ipmi_devices; struct ipmi_smi_watcher bmc_events; - struct ipmi_user_hndl ipmi_hndlrs; + const struct ipmi_user_hndl ipmi_hndlrs; struct mutex ipmi_lock; /* diff --git a/drivers/acpi/acpica/dbconvert.c b/drivers/acpi/acpica/dbconvert.c index 251f9477a984..857dbc43a9b1 100644 --- a/drivers/acpi/acpica/dbconvert.c +++ b/drivers/acpi/acpica/dbconvert.c @@ -242,7 +242,7 @@ acpi_status acpi_db_convert_to_package(char *string, union acpi_object *object) * * RETURN: Status * - * DESCRIPTION: Convert a typed and tokenized string to an union acpi_object. Typing: + * DESCRIPTION: Convert a typed and tokenized string to a union acpi_object. Typing: * 1) String objects were surrounded by quotes. * 2) Buffer objects were surrounded by parentheses. * 3) Package objects were surrounded by brackets "[]". diff --git a/drivers/acpi/acpica/nspredef.c b/drivers/acpi/acpica/nspredef.c index 3dbbecf22087..9d14b509529e 100644 --- a/drivers/acpi/acpica/nspredef.c +++ b/drivers/acpi/acpica/nspredef.c @@ -323,7 +323,7 @@ acpi_ns_check_reference(struct acpi_evaluate_info *info, /* * Check the reference object for the correct reference type (opcode). - * The only type of reference that can be converted to an union acpi_object is + * The only type of reference that can be converted to a union acpi_object is * a reference to a named object (reference class: NAME) */ if (return_object->reference.class == ACPI_REFCLASS_NAME) { diff --git a/drivers/acpi/acpica/nsxfeval.c b/drivers/acpi/acpica/nsxfeval.c index 8e365c0e766b..c944ff5c9c3d 100644 --- a/drivers/acpi/acpica/nsxfeval.c +++ b/drivers/acpi/acpica/nsxfeval.c @@ -495,9 +495,9 @@ static void acpi_ns_resolve_references(struct acpi_evaluate_info *info) /* * Two types of references are supported - those created by Index and * ref_of operators. A name reference (AML_NAMEPATH_OP) can be converted - * to an union acpi_object, so it is not dereferenced here. A ddb_handle + * to a union acpi_object, so it is not dereferenced here. A ddb_handle * (AML_LOAD_OP) cannot be dereferenced, nor can it be converted to - * an union acpi_object. + * a union acpi_object. */ switch (info->return_object->reference.class) { case ACPI_REFCLASS_INDEX: diff --git a/drivers/acpi/resource.c b/drivers/acpi/resource.c index 8b11d6d385dc..cd4c4271dc4c 100644 --- a/drivers/acpi/resource.c +++ b/drivers/acpi/resource.c @@ -406,7 +406,7 @@ static void acpi_dev_get_irqresource(struct resource *res, u32 gsi, } /* - * In IO-APIC mode, use overrided attribute. Two reasons: + * In IO-APIC mode, use overridden attribute. Two reasons: * 1. BIOS bug in DSDT * 2. BIOS uses IO-APIC mode Interrupt Source Override * diff --git a/drivers/acpi/spcr.c b/drivers/acpi/spcr.c index 2b5d0fac81f0..01c94669a2b0 100644 --- a/drivers/acpi/spcr.c +++ b/drivers/acpi/spcr.c @@ -46,7 +46,7 @@ static bool qdf2400_erratum_44_present(struct acpi_table_header *h) * console is registered and if @earlycon is true, earlycon is set up. * * When CONFIG_ACPI_SPCR_TABLE is defined, this function should be called - * from arch inintialization code as soon as the DT/ACPI decision is made. + * from arch initialization code as soon as the DT/ACPI decision is made. * */ int __init parse_spcr(bool earlycon) diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 4e5bf36c5f46..ef68232b5222 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c @@ -2034,7 +2034,7 @@ static int speed_down_verdict_cb(struct ata_ering_entry *ent, void *void_arg) * This is to expedite speed down decisions right after device is * initially configured. * - * The followings are speed down rules. #1 and #2 deal with + * The following are speed down rules. #1 and #2 deal with * DUBIOUS errors. * * 1. If more than one DUBIOUS_ATA_BUS or DUBIOUS_TOUT_HSM errors diff --git a/drivers/atm/ambassador.c b/drivers/atm/ambassador.c index f1a9198dfe5a..4a610795b585 100644 --- a/drivers/atm/ambassador.c +++ b/drivers/atm/ambassador.c @@ -2394,12 +2394,7 @@ static int __init amb_module_init (void) { PRINTD (DBG_FLOW|DBG_INIT, "init_module"); - // sanity check - cast needed as printk does not support %Zu - if (sizeof(amb_mem) != 4*16 + 4*12) { - PRINTK (KERN_ERR, "Fix amb_mem (is %lu words).", - (unsigned long) sizeof(amb_mem)); - return -ENOMEM; - } + BUILD_BUG_ON(sizeof(amb_mem) != 4*16 + 4*12); show_version(); diff --git a/drivers/atm/eni.c b/drivers/atm/eni.c index 623359e407aa..b042ec458544 100644 --- a/drivers/atm/eni.c +++ b/drivers/atm/eni.c @@ -2326,11 +2326,7 @@ static int __init eni_init(void) { struct sk_buff *skb; /* dummy for sizeof */ - if (sizeof(skb->cb) < sizeof(struct eni_skb_prv)) { - printk(KERN_ERR "eni_detect: skb->cb is too small (%Zd < %Zd)\n", - sizeof(skb->cb),sizeof(struct eni_skb_prv)); - return -EIO; - } + BUILD_BUG_ON(sizeof(skb->cb) < sizeof(struct eni_skb_prv)); return pci_register_driver(&eni_driver); } diff --git a/drivers/atm/firestream.c b/drivers/atm/firestream.c index 80c2ddcfa92c..22dcab952a24 100644 --- a/drivers/atm/firestream.c +++ b/drivers/atm/firestream.c @@ -895,7 +895,7 @@ static int fs_open(struct atm_vcc *atm_vcc) /* XXX handle qos parameters (rate limiting) ? */ vcc = kmalloc(sizeof(struct fs_vcc), GFP_KERNEL); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc VCC: %p(%Zd)\n", vcc, sizeof(struct fs_vcc)); + fs_dprintk (FS_DEBUG_ALLOC, "Alloc VCC: %p(%zd)\n", vcc, sizeof(struct fs_vcc)); if (!vcc) { clear_bit(ATM_VF_ADDR, &atm_vcc->flags); return -ENOMEM; @@ -946,7 +946,7 @@ static int fs_open(struct atm_vcc *atm_vcc) if (DO_DIRECTION (txtp)) { tc = kmalloc (sizeof (struct fs_transmit_config), GFP_KERNEL); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc tc: %p(%Zd)\n", + fs_dprintk (FS_DEBUG_ALLOC, "Alloc tc: %p(%zd)\n", tc, sizeof (struct fs_transmit_config)); if (!tc) { fs_dprintk (FS_DEBUG_OPEN, "fs: can't alloc transmit_config.\n"); @@ -1185,7 +1185,7 @@ static int fs_send (struct atm_vcc *atm_vcc, struct sk_buff *skb) vcc->last_skb = skb; td = kmalloc (sizeof (struct FS_BPENTRY), GFP_ATOMIC); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc transd: %p(%Zd)\n", td, sizeof (struct FS_BPENTRY)); + fs_dprintk (FS_DEBUG_ALLOC, "Alloc transd: %p(%zd)\n", td, sizeof (struct FS_BPENTRY)); if (!td) { /* Oops out of mem */ return -ENOMEM; @@ -1492,7 +1492,7 @@ static void top_off_fp (struct fs_dev *dev, struct freepool *fp, fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-skb: %p(%d)\n", skb, fp->bufsize); if (!skb) break; ne = kmalloc (sizeof (struct FS_BPENTRY), gfp_flags); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-d: %p(%Zd)\n", ne, sizeof (struct FS_BPENTRY)); + fs_dprintk (FS_DEBUG_ALLOC, "Alloc rec-d: %p(%zd)\n", ne, sizeof (struct FS_BPENTRY)); if (!ne) { fs_dprintk (FS_DEBUG_ALLOC, "Free rec-skb: %p\n", skb); dev_kfree_skb_any (skb); @@ -1803,7 +1803,7 @@ static int fs_init(struct fs_dev *dev) } dev->atm_vccs = kcalloc (dev->nchannels, sizeof (struct atm_vcc *), GFP_KERNEL); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%Zd)\n", + fs_dprintk (FS_DEBUG_ALLOC, "Alloc atmvccs: %p(%zd)\n", dev->atm_vccs, dev->nchannels * sizeof (struct atm_vcc *)); if (!dev->atm_vccs) { @@ -1911,7 +1911,7 @@ static int firestream_init_one(struct pci_dev *pci_dev, goto err_out; fs_dev = kzalloc (sizeof (struct fs_dev), GFP_KERNEL); - fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%Zd)\n", + fs_dprintk (FS_DEBUG_ALLOC, "Alloc fs-dev: %p(%zd)\n", fs_dev, sizeof (struct fs_dev)); if (!fs_dev) goto err_out; diff --git a/drivers/atm/horizon.c b/drivers/atm/horizon.c index 584aa881882b..2bf1ef1c3c78 100644 --- a/drivers/atm/horizon.c +++ b/drivers/atm/horizon.c @@ -2884,12 +2884,7 @@ static struct pci_driver hrz_driver = { /********** module entry **********/ static int __init hrz_module_init (void) { - // sanity check - cast is needed since printk does not support %Zu - if (sizeof(struct MEMMAP) != 128*1024/4) { - PRINTK (KERN_ERR, "Fix struct MEMMAP (is %lu fakewords).", - (unsigned long) sizeof(struct MEMMAP)); - return -ENOMEM; - } + BUILD_BUG_ON(sizeof(struct MEMMAP) != 128*1024/4); show_version(); diff --git a/drivers/atm/iphase.c b/drivers/atm/iphase.c index 8640bafeb471..a4fa6c82261e 100644 --- a/drivers/atm/iphase.c +++ b/drivers/atm/iphase.c @@ -21,7 +21,7 @@ supports a variety of varients of Interphase ATM PCI (i)Chip adapter card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) in terms of PHY type, the size of control memory and the size of - packet memory. The followings are the change log and history: + packet memory. The following are the change log and history: Bugfix the Mona's UBR driver. Modify the basic memory allocation and dma logic. diff --git a/drivers/atm/iphase.h b/drivers/atm/iphase.h index 53ecac5a2161..2beacf2fc1ec 100644 --- a/drivers/atm/iphase.h +++ b/drivers/atm/iphase.h @@ -21,7 +21,7 @@ supports a variety of varients of Interphase ATM PCI (i)Chip adapter card family (See www.iphase.com/products/ClassSheet.cfm?ClassID=ATM) in terms of PHY type, the size of control memory and the size of - packet memory. The followings are the change log and history: + packet memory. The following are the change log and history: Bugfix the Mona's UBR driver. Modify the basic memory allocation and dma logic. diff --git a/drivers/atm/lanai.c b/drivers/atm/lanai.c index 445505d9ea07..1a9bc51284b0 100644 --- a/drivers/atm/lanai.c +++ b/drivers/atm/lanai.c @@ -1389,7 +1389,7 @@ static void vcc_rx_aal5(struct lanai_vcc *lvcc, int endptr) if (n < 0) n += lanai_buf_size(&lvcc->rx.buf); APRINTK(n >= 0 && n < lanai_buf_size(&lvcc->rx.buf) && !(n & 15), - "vcc_rx_aal5: n out of range (%d/%Zu)\n", + "vcc_rx_aal5: n out of range (%d/%zu)\n", n, lanai_buf_size(&lvcc->rx.buf)); /* Recover the second-to-last word to get true pdu length */ if ((x = &end[-2]) < lvcc->rx.buf.start) @@ -1493,9 +1493,9 @@ static int lanai_get_sized_buffer(struct lanai_dev *lanai, return -ENOMEM; if (unlikely(lanai_buf_size(buf) < size)) printk(KERN_WARNING DEV_LABEL "(itf %d): wanted %d bytes " - "for %s buffer, got only %Zu\n", lanai->number, size, + "for %s buffer, got only %zu\n", lanai->number, size, name, lanai_buf_size(buf)); - DPRINTK("Allocated %Zu byte %s buffer\n", lanai_buf_size(buf), name); + DPRINTK("Allocated %zu byte %s buffer\n", lanai_buf_size(buf), name); return 0; } @@ -1586,7 +1586,7 @@ static int service_buffer_allocate(struct lanai_dev *lanai) lanai->pci); if (unlikely(lanai->service.start == NULL)) return -ENOMEM; - DPRINTK("allocated service buffer at 0x%08lX, size %Zu(%d)\n", + DPRINTK("allocated service buffer at 0x%08lX, size %zu(%d)\n", (unsigned long) lanai->service.start, lanai_buf_size(&lanai->service), lanai_buf_size_cardorder(&lanai->service)); @@ -2467,8 +2467,8 @@ static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page) (lanai->status & STATUS_LED) ? 1 : 0, (lanai->status & STATUS_GPIN) ? 1 : 0); if (left-- == 0) - return sprintf(page, "global buffer sizes: service=%Zu, " - "aal0_rx=%Zu\n", lanai_buf_size(&lanai->service), + return sprintf(page, "global buffer sizes: service=%zu, " + "aal0_rx=%zu\n", lanai_buf_size(&lanai->service), lanai->naal0 ? lanai_buf_size(&lanai->aal0buf) : 0); if (left-- == 0) { get_statistics(lanai); @@ -2513,7 +2513,7 @@ static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page) left += sprintf(&page[left], ",\n rx_AAL=%d", lvcc->rx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0); if (lvcc->rx.atmvcc->qos.aal == ATM_AAL5) - left += sprintf(&page[left], ", rx_buf_size=%Zu, " + left += sprintf(&page[left], ", rx_buf_size=%zu, " "rx_bad_len=%u,\n rx_service_trash=%u, " "rx_service_stream=%u, rx_bad_crc=%u", lanai_buf_size(&lvcc->rx.buf), @@ -2524,7 +2524,7 @@ static int lanai_proc_read(struct atm_dev *atmdev, loff_t *pos, char *page) } if (lvcc->tx.atmvcc != NULL) left += sprintf(&page[left], ",\n tx_AAL=%d, " - "tx_buf_size=%Zu, tx_qos=%cBR, tx_backlogged=%c", + "tx_buf_size=%zu, tx_qos=%cBR, tx_backlogged=%c", lvcc->tx.atmvcc->qos.aal == ATM_AAL5 ? 5 : 0, lanai_buf_size(&lvcc->tx.buf), lvcc->tx.atmvcc == lanai->cbrvcc ? 'C' : 'U', diff --git a/drivers/atm/nicstar.c b/drivers/atm/nicstar.c index cb28579e8a94..d879f3bca107 100644 --- a/drivers/atm/nicstar.c +++ b/drivers/atm/nicstar.c @@ -1980,13 +1980,12 @@ static void dequeue_rx(ns_dev * card, ns_rsqe * rsqe) card->lbfqc = ns_stat_lfbqc_get(stat); id = le32_to_cpu(rsqe->buffer_handle); - skb = idr_find(&card->idr, id); + skb = idr_remove(&card->idr, id); if (!skb) { RXPRINTK(KERN_ERR - "nicstar%d: idr_find() failed!\n", card->index); + "nicstar%d: skb not found!\n", card->index); return; } - idr_remove(&card->idr, id); dma_sync_single_for_cpu(&card->pcidev->dev, NS_PRV_DMA(skb), (NS_PRV_BUFTYPE(skb) == BUF_SM diff --git a/drivers/block/drbd/drbd_main.c b/drivers/block/drbd/drbd_main.c index 615e5b5178a0..116509852a34 100644 --- a/drivers/block/drbd/drbd_main.c +++ b/drivers/block/drbd/drbd_main.c @@ -2915,11 +2915,9 @@ out_idr_remove_vol: idr_remove(&connection->peer_devices, vnr); out_idr_remove_from_resource: for_each_connection(connection, resource) { - peer_device = idr_find(&connection->peer_devices, vnr); - if (peer_device) { - idr_remove(&connection->peer_devices, vnr); + peer_device = idr_remove(&connection->peer_devices, vnr); + if (peer_device) kref_put(&connection->kref, drbd_destroy_connection); - } } for_each_peer_device_safe(peer_device, tmp_peer_device, device) { list_del(&peer_device->peer_devices); diff --git a/drivers/block/loop.c b/drivers/block/loop.c index 304377182c1a..4b52a1690329 100644 --- a/drivers/block/loop.c +++ b/drivers/block/loop.c @@ -186,7 +186,7 @@ static void __loop_update_dio(struct loop_device *lo, bool dio) * * TODO: the above condition may be loosed in the future, and * direct I/O may be switched runtime at that time because most - * of requests in sane appplications should be PAGE_SIZE algined + * of requests in sane applications should be PAGE_SIZE aligned */ if (dio) { if (queue_logical_block_size(lo->lo_queue) >= sb_bsize && diff --git a/drivers/block/rbd.c b/drivers/block/rbd.c index 362cecc77130..4d6807723798 100644 --- a/drivers/block/rbd.c +++ b/drivers/block/rbd.c @@ -123,9 +123,11 @@ static int atomic_dec_return_safe(atomic_t *v) #define RBD_FEATURE_LAYERING (1<<0) #define RBD_FEATURE_STRIPINGV2 (1<<1) #define RBD_FEATURE_EXCLUSIVE_LOCK (1<<2) +#define RBD_FEATURE_DATA_POOL (1<<7) #define RBD_FEATURES_ALL (RBD_FEATURE_LAYERING | \ RBD_FEATURE_STRIPINGV2 | \ - RBD_FEATURE_EXCLUSIVE_LOCK) + RBD_FEATURE_EXCLUSIVE_LOCK | \ + RBD_FEATURE_DATA_POOL) /* Features supported by this (client software) implementation. */ @@ -144,10 +146,9 @@ struct rbd_image_header { /* These six fields never change for a given rbd image */ char *object_prefix; __u8 obj_order; - __u8 crypt_type; - __u8 comp_type; u64 stripe_unit; u64 stripe_count; + s64 data_pool_id; u64 features; /* Might be changeable someday? */ /* The remaining fields need to be updated occasionally */ @@ -230,7 +231,7 @@ enum obj_req_flags { }; struct rbd_obj_request { - const char *object_name; + u64 object_no; u64 offset; /* object start byte */ u64 length; /* bytes from offset */ unsigned long flags; @@ -438,7 +439,6 @@ static DEFINE_SPINLOCK(rbd_client_list_lock); static struct kmem_cache *rbd_img_request_cache; static struct kmem_cache *rbd_obj_request_cache; -static struct kmem_cache *rbd_segment_name_cache; static int rbd_major; static DEFINE_IDA(rbd_dev_id_ida); @@ -973,6 +973,30 @@ static bool rbd_dev_ondisk_valid(struct rbd_image_header_ondisk *ondisk) } /* + * returns the size of an object in the image + */ +static u32 rbd_obj_bytes(struct rbd_image_header *header) +{ + return 1U << header->obj_order; +} + +static void rbd_init_layout(struct rbd_device *rbd_dev) +{ + if (rbd_dev->header.stripe_unit == 0 || + rbd_dev->header.stripe_count == 0) { + rbd_dev->header.stripe_unit = rbd_obj_bytes(&rbd_dev->header); + rbd_dev->header.stripe_count = 1; + } + + rbd_dev->layout.stripe_unit = rbd_dev->header.stripe_unit; + rbd_dev->layout.stripe_count = rbd_dev->header.stripe_count; + rbd_dev->layout.object_size = rbd_obj_bytes(&rbd_dev->header); + rbd_dev->layout.pool_id = rbd_dev->header.data_pool_id == CEPH_NOPOOL ? + rbd_dev->spec->pool_id : rbd_dev->header.data_pool_id; + RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); +} + +/* * Fill an rbd image header with information from the given format 1 * on-disk header. */ @@ -992,15 +1016,11 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev, /* Allocate this now to avoid having to handle failure below */ if (first_time) { - size_t len; - - len = strnlen(ondisk->object_prefix, - sizeof (ondisk->object_prefix)); - object_prefix = kmalloc(len + 1, GFP_KERNEL); + object_prefix = kstrndup(ondisk->object_prefix, + sizeof(ondisk->object_prefix), + GFP_KERNEL); if (!object_prefix) return -ENOMEM; - memcpy(object_prefix, ondisk->object_prefix, len); - object_prefix[len] = '\0'; } /* Allocate the snapshot context and fill it in */ @@ -1051,12 +1071,7 @@ static int rbd_header_from_disk(struct rbd_device *rbd_dev, if (first_time) { header->object_prefix = object_prefix; header->obj_order = ondisk->options.order; - header->crypt_type = ondisk->options.crypt_type; - header->comp_type = ondisk->options.comp_type; - /* The rest aren't used for format 1 images */ - header->stripe_unit = 0; - header->stripe_count = 0; - header->features = 0; + rbd_init_layout(rbd_dev); } else { ceph_put_snap_context(header->snapc); kfree(header->snap_names); @@ -1232,42 +1247,9 @@ static void rbd_dev_mapping_clear(struct rbd_device *rbd_dev) rbd_dev->mapping.features = 0; } -static void rbd_segment_name_free(const char *name) -{ - /* The explicit cast here is needed to drop the const qualifier */ - - kmem_cache_free(rbd_segment_name_cache, (void *)name); -} - -static const char *rbd_segment_name(struct rbd_device *rbd_dev, u64 offset) -{ - char *name; - u64 segment; - int ret; - char *name_format; - - name = kmem_cache_alloc(rbd_segment_name_cache, GFP_NOIO); - if (!name) - return NULL; - segment = offset >> rbd_dev->header.obj_order; - name_format = "%s.%012llx"; - if (rbd_dev->image_format == 2) - name_format = "%s.%016llx"; - ret = snprintf(name, CEPH_MAX_OID_NAME_LEN + 1, name_format, - rbd_dev->header.object_prefix, segment); - if (ret < 0 || ret > CEPH_MAX_OID_NAME_LEN) { - pr_err("error formatting segment name for #%llu (%d)\n", - segment, ret); - rbd_segment_name_free(name); - name = NULL; - } - - return name; -} - static u64 rbd_segment_offset(struct rbd_device *rbd_dev, u64 offset) { - u64 segment_size = (u64) 1 << rbd_dev->header.obj_order; + u64 segment_size = rbd_obj_bytes(&rbd_dev->header); return offset & (segment_size - 1); } @@ -1275,7 +1257,7 @@ static u64 rbd_segment_offset(struct rbd_device *rbd_dev, u64 offset) static u64 rbd_segment_length(struct rbd_device *rbd_dev, u64 offset, u64 length) { - u64 segment_size = (u64) 1 << rbd_dev->header.obj_order; + u64 segment_size = rbd_obj_bytes(&rbd_dev->header); offset &= segment_size - 1; @@ -1287,14 +1269,6 @@ static u64 rbd_segment_length(struct rbd_device *rbd_dev, } /* - * returns the size of an object in the image - */ -static u64 rbd_obj_bytes(struct rbd_image_header *header) -{ - return 1 << header->obj_order; -} - -/* * bio helpers */ @@ -1623,7 +1597,9 @@ static void rbd_obj_request_submit(struct rbd_obj_request *obj_request) { struct ceph_osd_request *osd_req = obj_request->osd_req; - dout("%s %p osd_req %p\n", __func__, obj_request, osd_req); + dout("%s %p object_no %016llx %llu~%llu osd_req %p\n", __func__, + obj_request, obj_request->object_no, obj_request->offset, + obj_request->length, osd_req); if (obj_request_img_data_test(obj_request)) { WARN_ON(obj_request->callback != rbd_img_obj_callback); rbd_img_request_get(obj_request->img_request); @@ -1631,44 +1607,6 @@ static void rbd_obj_request_submit(struct rbd_obj_request *obj_request) ceph_osdc_start_request(osd_req->r_osdc, osd_req, false); } -static void rbd_obj_request_end(struct rbd_obj_request *obj_request) -{ - dout("%s %p\n", __func__, obj_request); - ceph_osdc_cancel_request(obj_request->osd_req); -} - -/* - * Wait for an object request to complete. If interrupted, cancel the - * underlying osd request. - * - * @timeout: in jiffies, 0 means "wait forever" - */ -static int __rbd_obj_request_wait(struct rbd_obj_request *obj_request, - unsigned long timeout) -{ - long ret; - - dout("%s %p\n", __func__, obj_request); - ret = wait_for_completion_interruptible_timeout( - &obj_request->completion, - ceph_timeout_jiffies(timeout)); - if (ret <= 0) { - if (ret == 0) - ret = -ETIMEDOUT; - rbd_obj_request_end(obj_request); - } else { - ret = 0; - } - - dout("%s %p ret %d\n", __func__, obj_request, (int)ret); - return ret; -} - -static int rbd_obj_request_wait(struct rbd_obj_request *obj_request) -{ - return __rbd_obj_request_wait(obj_request, 0); -} - static void rbd_img_request_complete(struct rbd_img_request *img_request) { @@ -1955,8 +1893,8 @@ static void rbd_osd_req_callback(struct ceph_osd_request *osd_req) rbd_osd_call_callback(obj_request); break; default: - rbd_warn(NULL, "%s: unsupported op %hu", - obj_request->object_name, (unsigned short) opcode); + rbd_warn(NULL, "unexpected OSD op: object_no %016llx opcode %d", + obj_request->object_no, opcode); break; } @@ -1980,6 +1918,40 @@ static void rbd_osd_req_format_write(struct rbd_obj_request *obj_request) osd_req->r_data_offset = obj_request->offset; } +static struct ceph_osd_request * +__rbd_osd_req_create(struct rbd_device *rbd_dev, + struct ceph_snap_context *snapc, + int num_ops, unsigned int flags, + struct rbd_obj_request *obj_request) +{ + struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; + struct ceph_osd_request *req; + const char *name_format = rbd_dev->image_format == 1 ? + RBD_V1_DATA_FORMAT : RBD_V2_DATA_FORMAT; + + req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false, GFP_NOIO); + if (!req) + return NULL; + + req->r_flags = flags; + req->r_callback = rbd_osd_req_callback; + req->r_priv = obj_request; + + req->r_base_oloc.pool = rbd_dev->layout.pool_id; + if (ceph_oid_aprintf(&req->r_base_oid, GFP_NOIO, name_format, + rbd_dev->header.object_prefix, obj_request->object_no)) + goto err_req; + + if (ceph_osdc_alloc_messages(req, GFP_NOIO)) + goto err_req; + + return req; + +err_req: + ceph_osdc_put_request(req); + return NULL; +} + /* * Create an osd request. A read request has one osd op (read). * A write request has either one (watch) or two (hint+write) osd ops. @@ -1993,8 +1965,6 @@ static struct ceph_osd_request *rbd_osd_req_create( struct rbd_obj_request *obj_request) { struct ceph_snap_context *snapc = NULL; - struct ceph_osd_client *osdc; - struct ceph_osd_request *osd_req; if (obj_request_img_data_test(obj_request) && (op_type == OBJ_OP_DISCARD || op_type == OBJ_OP_WRITE)) { @@ -2009,35 +1979,9 @@ static struct ceph_osd_request *rbd_osd_req_create( rbd_assert(num_ops == 1 || ((op_type == OBJ_OP_WRITE) && num_ops == 2)); - /* Allocate and initialize the request, for the num_ops ops */ - - osdc = &rbd_dev->rbd_client->client->osdc; - osd_req = ceph_osdc_alloc_request(osdc, snapc, num_ops, false, - GFP_NOIO); - if (!osd_req) - goto fail; - - if (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD) - osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK; - else - osd_req->r_flags = CEPH_OSD_FLAG_READ; - - osd_req->r_callback = rbd_osd_req_callback; - osd_req->r_priv = obj_request; - - osd_req->r_base_oloc.pool = rbd_dev->layout.pool_id; - if (ceph_oid_aprintf(&osd_req->r_base_oid, GFP_NOIO, "%s", - obj_request->object_name)) - goto fail; - - if (ceph_osdc_alloc_messages(osd_req, GFP_NOIO)) - goto fail; - - return osd_req; - -fail: - ceph_osdc_put_request(osd_req); - return NULL; + return __rbd_osd_req_create(rbd_dev, snapc, num_ops, + (op_type == OBJ_OP_WRITE || op_type == OBJ_OP_DISCARD) ? + CEPH_OSD_FLAG_WRITE : CEPH_OSD_FLAG_READ, obj_request); } /* @@ -2050,10 +1994,6 @@ static struct ceph_osd_request * rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request) { struct rbd_img_request *img_request; - struct ceph_snap_context *snapc; - struct rbd_device *rbd_dev; - struct ceph_osd_client *osdc; - struct ceph_osd_request *osd_req; int num_osd_ops = 3; rbd_assert(obj_request_img_data_test(obj_request)); @@ -2065,77 +2005,34 @@ rbd_osd_req_create_copyup(struct rbd_obj_request *obj_request) if (img_request_discard_test(img_request)) num_osd_ops = 2; - /* Allocate and initialize the request, for all the ops */ - - snapc = img_request->snapc; - rbd_dev = img_request->rbd_dev; - osdc = &rbd_dev->rbd_client->client->osdc; - osd_req = ceph_osdc_alloc_request(osdc, snapc, num_osd_ops, - false, GFP_NOIO); - if (!osd_req) - goto fail; - - osd_req->r_flags = CEPH_OSD_FLAG_WRITE | CEPH_OSD_FLAG_ONDISK; - osd_req->r_callback = rbd_osd_req_callback; - osd_req->r_priv = obj_request; - - osd_req->r_base_oloc.pool = rbd_dev->layout.pool_id; - if (ceph_oid_aprintf(&osd_req->r_base_oid, GFP_NOIO, "%s", - obj_request->object_name)) - goto fail; - - if (ceph_osdc_alloc_messages(osd_req, GFP_NOIO)) - goto fail; - - return osd_req; - -fail: - ceph_osdc_put_request(osd_req); - return NULL; + return __rbd_osd_req_create(img_request->rbd_dev, + img_request->snapc, num_osd_ops, + CEPH_OSD_FLAG_WRITE, obj_request); } - static void rbd_osd_req_destroy(struct ceph_osd_request *osd_req) { ceph_osdc_put_request(osd_req); } -/* object_name is assumed to be a non-null pointer and NUL-terminated */ - -static struct rbd_obj_request *rbd_obj_request_create(const char *object_name, - u64 offset, u64 length, - enum obj_request_type type) +static struct rbd_obj_request * +rbd_obj_request_create(enum obj_request_type type) { struct rbd_obj_request *obj_request; - size_t size; - char *name; rbd_assert(obj_request_type_valid(type)); - size = strlen(object_name) + 1; - name = kmalloc(size, GFP_NOIO); - if (!name) - return NULL; - obj_request = kmem_cache_zalloc(rbd_obj_request_cache, GFP_NOIO); - if (!obj_request) { - kfree(name); + if (!obj_request) return NULL; - } - obj_request->object_name = memcpy(name, object_name, size); - obj_request->offset = offset; - obj_request->length = length; - obj_request->flags = 0; obj_request->which = BAD_WHICH; obj_request->type = type; INIT_LIST_HEAD(&obj_request->links); init_completion(&obj_request->completion); kref_init(&obj_request->kref); - dout("%s: \"%s\" %llu/%llu %d -> obj %p\n", __func__, object_name, - offset, length, (int)type, obj_request); - + dout("%s %p\n", __func__, obj_request); return obj_request; } @@ -2170,8 +2067,6 @@ static void rbd_obj_request_destroy(struct kref *kref) break; } - kfree(obj_request->object_name); - obj_request->object_name = NULL; kmem_cache_free(rbd_obj_request_cache, obj_request); } @@ -2546,22 +2441,18 @@ static int rbd_img_request_fill(struct rbd_img_request *img_request, while (resid) { struct ceph_osd_request *osd_req; - const char *object_name; - u64 offset; - u64 length; + u64 object_no = img_offset >> rbd_dev->header.obj_order; + u64 offset = rbd_segment_offset(rbd_dev, img_offset); + u64 length = rbd_segment_length(rbd_dev, img_offset, resid); - object_name = rbd_segment_name(rbd_dev, img_offset); - if (!object_name) - goto out_unwind; - offset = rbd_segment_offset(rbd_dev, img_offset); - length = rbd_segment_length(rbd_dev, img_offset, resid); - obj_request = rbd_obj_request_create(object_name, - offset, length, type); - /* object request has its own copy of the object name */ - rbd_segment_name_free(object_name); + obj_request = rbd_obj_request_create(type); if (!obj_request) goto out_unwind; + obj_request->object_no = object_no; + obj_request->offset = offset; + obj_request->length = length; + /* * set obj_request->img_request before creating the * osd_request so that it gets the right snapc @@ -2771,7 +2662,7 @@ static int rbd_img_obj_parent_read_full(struct rbd_obj_request *obj_request) * child image to which the original request was to be sent. */ img_offset = obj_request->img_offset - obj_request->offset; - length = (u64)1 << rbd_dev->header.obj_order; + length = rbd_obj_bytes(&rbd_dev->header); /* * There is no defined parent data beyond the parent @@ -2900,11 +2791,12 @@ static int rbd_img_obj_exists_submit(struct rbd_obj_request *obj_request) size_t size; int ret; - stat_request = rbd_obj_request_create(obj_request->object_name, 0, 0, - OBJ_REQUEST_PAGES); + stat_request = rbd_obj_request_create(OBJ_REQUEST_PAGES); if (!stat_request) return -ENOMEM; + stat_request->object_no = obj_request->object_no; + stat_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1, stat_request); if (!stat_request->osd_req) { @@ -3983,17 +3875,17 @@ out: * returned in the outbound buffer, or a negative error code. */ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, - const char *object_name, - const char *class_name, + struct ceph_object_id *oid, + struct ceph_object_locator *oloc, const char *method_name, const void *outbound, size_t outbound_size, void *inbound, size_t inbound_size) { - struct rbd_obj_request *obj_request; - struct page **pages; - u32 page_count; + struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; + struct page *req_page = NULL; + struct page *reply_page; int ret; /* @@ -4003,61 +3895,35 @@ static int rbd_obj_method_sync(struct rbd_device *rbd_dev, * method. Currently if this is present it will be a * snapshot id. */ - page_count = (u32)calc_pages_for(0, inbound_size); - pages = ceph_alloc_page_vector(page_count, GFP_KERNEL); - if (IS_ERR(pages)) - return PTR_ERR(pages); - - ret = -ENOMEM; - obj_request = rbd_obj_request_create(object_name, 0, inbound_size, - OBJ_REQUEST_PAGES); - if (!obj_request) - goto out; + if (outbound) { + if (outbound_size > PAGE_SIZE) + return -E2BIG; - obj_request->pages = pages; - obj_request->page_count = page_count; - - obj_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1, - obj_request); - if (!obj_request->osd_req) - goto out; - - osd_req_op_cls_init(obj_request->osd_req, 0, CEPH_OSD_OP_CALL, - class_name, method_name); - if (outbound_size) { - struct ceph_pagelist *pagelist; - - pagelist = kmalloc(sizeof (*pagelist), GFP_NOFS); - if (!pagelist) - goto out; + req_page = alloc_page(GFP_KERNEL); + if (!req_page) + return -ENOMEM; - ceph_pagelist_init(pagelist); - ceph_pagelist_append(pagelist, outbound, outbound_size); - osd_req_op_cls_request_data_pagelist(obj_request->osd_req, 0, - pagelist); + memcpy(page_address(req_page), outbound, outbound_size); } - osd_req_op_cls_response_data_pages(obj_request->osd_req, 0, - obj_request->pages, inbound_size, - 0, false, false); - - rbd_obj_request_submit(obj_request); - ret = rbd_obj_request_wait(obj_request); - if (ret) - goto out; - ret = obj_request->result; - if (ret < 0) - goto out; + reply_page = alloc_page(GFP_KERNEL); + if (!reply_page) { + if (req_page) + __free_page(req_page); + return -ENOMEM; + } - rbd_assert(obj_request->xferred < (u64)INT_MAX); - ret = (int)obj_request->xferred; - ceph_copy_from_page_vector(pages, inbound, 0, obj_request->xferred); -out: - if (obj_request) - rbd_obj_request_put(obj_request); - else - ceph_release_page_vector(pages, page_count); + ret = ceph_osdc_call(osdc, oid, oloc, RBD_DRV_NAME, method_name, + CEPH_OSD_FLAG_READ, req_page, outbound_size, + reply_page, &inbound_size); + if (!ret) { + memcpy(inbound, page_address(reply_page), inbound_size); + ret = inbound_size; + } + if (req_page) + __free_page(req_page); + __free_page(reply_page); return ret; } @@ -4256,63 +4122,46 @@ static void rbd_free_disk(struct rbd_device *rbd_dev) } static int rbd_obj_read_sync(struct rbd_device *rbd_dev, - const char *object_name, - u64 offset, u64 length, void *buf) + struct ceph_object_id *oid, + struct ceph_object_locator *oloc, + void *buf, int buf_len) { - struct rbd_obj_request *obj_request; - struct page **pages = NULL; - u32 page_count; - size_t size; + struct ceph_osd_client *osdc = &rbd_dev->rbd_client->client->osdc; + struct ceph_osd_request *req; + struct page **pages; + int num_pages = calc_pages_for(0, buf_len); int ret; - page_count = (u32) calc_pages_for(offset, length); - pages = ceph_alloc_page_vector(page_count, GFP_KERNEL); - if (IS_ERR(pages)) - return PTR_ERR(pages); - - ret = -ENOMEM; - obj_request = rbd_obj_request_create(object_name, offset, length, - OBJ_REQUEST_PAGES); - if (!obj_request) - goto out; - - obj_request->pages = pages; - obj_request->page_count = page_count; - - obj_request->osd_req = rbd_osd_req_create(rbd_dev, OBJ_OP_READ, 1, - obj_request); - if (!obj_request->osd_req) - goto out; + req = ceph_osdc_alloc_request(osdc, NULL, 1, false, GFP_KERNEL); + if (!req) + return -ENOMEM; - osd_req_op_extent_init(obj_request->osd_req, 0, CEPH_OSD_OP_READ, - offset, length, 0, 0); - osd_req_op_extent_osd_data_pages(obj_request->osd_req, 0, - obj_request->pages, - obj_request->length, - obj_request->offset & ~PAGE_MASK, - false, false); + ceph_oid_copy(&req->r_base_oid, oid); + ceph_oloc_copy(&req->r_base_oloc, oloc); + req->r_flags = CEPH_OSD_FLAG_READ; - rbd_obj_request_submit(obj_request); - ret = rbd_obj_request_wait(obj_request); + ret = ceph_osdc_alloc_messages(req, GFP_KERNEL); if (ret) - goto out; + goto out_req; - ret = obj_request->result; - if (ret < 0) - goto out; + pages = ceph_alloc_page_vector(num_pages, GFP_KERNEL); + if (IS_ERR(pages)) { + ret = PTR_ERR(pages); + goto out_req; + } - rbd_assert(obj_request->xferred <= (u64) SIZE_MAX); - size = (size_t) obj_request->xferred; - ceph_copy_from_page_vector(pages, buf, 0, size); - rbd_assert(size <= (size_t)INT_MAX); - ret = (int)size; -out: - if (obj_request) - rbd_obj_request_put(obj_request); - else - ceph_release_page_vector(pages, page_count); + osd_req_op_extent_init(req, 0, CEPH_OSD_OP_READ, 0, buf_len, 0, 0); + osd_req_op_extent_osd_data_pages(req, 0, pages, buf_len, 0, false, + true); + + ceph_osdc_start_request(osdc, req, false); + ret = ceph_osdc_wait_request(osdc, req); + if (ret >= 0) + ceph_copy_from_page_vector(pages, buf, 0, ret); +out_req: + ceph_osdc_put_request(req); return ret; } @@ -4348,8 +4197,8 @@ static int rbd_dev_v1_header_info(struct rbd_device *rbd_dev) if (!ondisk) return -ENOMEM; - ret = rbd_obj_read_sync(rbd_dev, rbd_dev->header_oid.name, - 0, size, ondisk); + ret = rbd_obj_read_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, ondisk, size); if (ret < 0) goto out; if ((size_t)ret < size) { @@ -4781,7 +4630,7 @@ static const struct attribute_group *rbd_attr_groups[] = { static void rbd_dev_release(struct device *dev); -static struct device_type rbd_device_type = { +static const struct device_type rbd_device_type = { .name = "rbd", .groups = rbd_attr_groups, .release = rbd_dev_release, @@ -4876,8 +4725,9 @@ static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc, INIT_LIST_HEAD(&rbd_dev->node); init_rwsem(&rbd_dev->header_rwsem); + rbd_dev->header.data_pool_id = CEPH_NOPOOL; ceph_oid_init(&rbd_dev->header_oid); - ceph_oloc_init(&rbd_dev->header_oloc); + rbd_dev->header_oloc.pool = spec->pool_id; mutex_init(&rbd_dev->watch_mutex); rbd_dev->watch_state = RBD_WATCH_STATE_UNREGISTERED; @@ -4899,12 +4749,6 @@ static struct rbd_device *__rbd_dev_create(struct rbd_client *rbdc, rbd_dev->rbd_client = rbdc; rbd_dev->spec = spec; - rbd_dev->layout.stripe_unit = 1 << RBD_MAX_OBJ_ORDER; - rbd_dev->layout.stripe_count = 1; - rbd_dev->layout.object_size = 1 << RBD_MAX_OBJ_ORDER; - rbd_dev->layout.pool_id = spec->pool_id; - RCU_INIT_POINTER(rbd_dev->layout.pool_ns, NULL); - return rbd_dev; } @@ -4970,10 +4814,10 @@ static int _rbd_dev_v2_snap_size(struct rbd_device *rbd_dev, u64 snap_id, __le64 size; } __attribute__ ((packed)) size_buf = { 0 }; - ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_oid.name, - "rbd", "get_size", - &snapid, sizeof (snapid), - &size_buf, sizeof (size_buf)); + ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, "get_size", + &snapid, sizeof(snapid), + &size_buf, sizeof(size_buf)); dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) return ret; @@ -5010,9 +4854,9 @@ static int rbd_dev_v2_object_prefix(struct rbd_device *rbd_dev) if (!reply_buf) return -ENOMEM; - ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_oid.name, - "rbd", "get_object_prefix", NULL, 0, - reply_buf, RBD_OBJ_PREFIX_LEN_MAX); + ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, "get_object_prefix", + NULL, 0, reply_buf, RBD_OBJ_PREFIX_LEN_MAX); dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) goto out; @@ -5045,10 +4889,10 @@ static int _rbd_dev_v2_snap_features(struct rbd_device *rbd_dev, u64 snap_id, u64 unsup; int ret; - ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_oid.name, - "rbd", "get_features", - &snapid, sizeof (snapid), - &features_buf, sizeof (features_buf)); + ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, "get_features", + &snapid, sizeof(snapid), + &features_buf, sizeof(features_buf)); dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) return ret; @@ -5107,10 +4951,9 @@ static int rbd_dev_v2_parent_info(struct rbd_device *rbd_dev) } snapid = cpu_to_le64(rbd_dev->spec->snap_id); - ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_oid.name, - "rbd", "get_parent", - &snapid, sizeof (snapid), - reply_buf, size); + ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, "get_parent", + &snapid, sizeof(snapid), reply_buf, size); dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) goto out_err; @@ -5210,9 +5053,9 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) u64 stripe_count; int ret; - ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_oid.name, - "rbd", "get_stripe_unit_count", NULL, 0, - (char *)&striping_info_buf, size); + ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, "get_stripe_unit_count", + NULL, 0, &striping_info_buf, size); dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) return ret; @@ -5226,7 +5069,7 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) * out, and only fail if the image has non-default values. */ ret = -EINVAL; - obj_size = (u64)1 << rbd_dev->header.obj_order; + obj_size = rbd_obj_bytes(&rbd_dev->header); p = &striping_info_buf; stripe_unit = ceph_decode_64(&p); if (stripe_unit != obj_size) { @@ -5247,8 +5090,27 @@ static int rbd_dev_v2_striping_info(struct rbd_device *rbd_dev) return 0; } +static int rbd_dev_v2_data_pool(struct rbd_device *rbd_dev) +{ + __le64 data_pool_id; + int ret; + + ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, "get_data_pool", + NULL, 0, &data_pool_id, sizeof(data_pool_id)); + if (ret < 0) + return ret; + if (ret < sizeof(data_pool_id)) + return -EBADMSG; + + rbd_dev->header.data_pool_id = le64_to_cpu(data_pool_id); + WARN_ON(rbd_dev->header.data_pool_id == CEPH_NOPOOL); + return 0; +} + static char *rbd_dev_image_name(struct rbd_device *rbd_dev) { + CEPH_DEFINE_OID_ONSTACK(oid); size_t image_id_size; char *image_id; void *p; @@ -5276,10 +5138,10 @@ static char *rbd_dev_image_name(struct rbd_device *rbd_dev) if (!reply_buf) goto out; - ret = rbd_obj_method_sync(rbd_dev, RBD_DIRECTORY, - "rbd", "dir_get_name", - image_id, image_id_size, - reply_buf, size); + ceph_oid_printf(&oid, "%s", RBD_DIRECTORY); + ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, + "dir_get_name", image_id, image_id_size, + reply_buf, size); if (ret < 0) goto out; p = reply_buf; @@ -5458,9 +5320,9 @@ static int rbd_dev_v2_snap_context(struct rbd_device *rbd_dev) if (!reply_buf) return -ENOMEM; - ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_oid.name, - "rbd", "get_snapcontext", NULL, 0, - reply_buf, size); + ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, "get_snapcontext", + NULL, 0, reply_buf, size); dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) goto out; @@ -5523,10 +5385,9 @@ static const char *rbd_dev_v2_snap_name(struct rbd_device *rbd_dev, return ERR_PTR(-ENOMEM); snapid = cpu_to_le64(snap_id); - ret = rbd_obj_method_sync(rbd_dev, rbd_dev->header_oid.name, - "rbd", "get_snapshot_name", - &snapid, sizeof (snapid), - reply_buf, size); + ret = rbd_obj_method_sync(rbd_dev, &rbd_dev->header_oid, + &rbd_dev->header_oloc, "get_snapshot_name", + &snapid, sizeof(snapid), reply_buf, size); dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret < 0) { snap_name = ERR_PTR(ret); @@ -5833,7 +5694,7 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev) { int ret; size_t size; - char *object_name; + CEPH_DEFINE_OID_ONSTACK(oid); void *response; char *image_id; @@ -5853,12 +5714,12 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev) * First, see if the format 2 image id file exists, and if * so, get the image's persistent id from it. */ - size = sizeof (RBD_ID_PREFIX) + strlen(rbd_dev->spec->image_name); - object_name = kmalloc(size, GFP_NOIO); - if (!object_name) - return -ENOMEM; - sprintf(object_name, "%s%s", RBD_ID_PREFIX, rbd_dev->spec->image_name); - dout("rbd id object name is %s\n", object_name); + ret = ceph_oid_aprintf(&oid, GFP_KERNEL, "%s%s", RBD_ID_PREFIX, + rbd_dev->spec->image_name); + if (ret) + return ret; + + dout("rbd id object name is %s\n", oid.name); /* Response will be an encoded string, which includes a length */ @@ -5871,9 +5732,9 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev) /* If it doesn't exist we'll assume it's a format 1 image */ - ret = rbd_obj_method_sync(rbd_dev, object_name, - "rbd", "get_id", NULL, 0, - response, RBD_IMAGE_ID_LEN_MAX); + ret = rbd_obj_method_sync(rbd_dev, &oid, &rbd_dev->header_oloc, + "get_id", NULL, 0, + response, RBD_IMAGE_ID_LEN_MAX); dout("%s: rbd_obj_method_sync returned %d\n", __func__, ret); if (ret == -ENOENT) { image_id = kstrdup("", GFP_KERNEL); @@ -5896,8 +5757,7 @@ static int rbd_dev_image_id(struct rbd_device *rbd_dev) } out: kfree(response); - kfree(object_name); - + ceph_oid_destroy(&oid); return ret; } @@ -5944,14 +5804,20 @@ static int rbd_dev_v2_header_onetime(struct rbd_device *rbd_dev) if (ret < 0) goto out_err; } - /* No support for crypto and compression type format 2 images */ + if (rbd_dev->header.features & RBD_FEATURE_DATA_POOL) { + ret = rbd_dev_v2_data_pool(rbd_dev); + if (ret) + goto out_err; + } + + rbd_init_layout(rbd_dev); return 0; + out_err: rbd_dev->header.features = 0; kfree(rbd_dev->header.object_prefix); rbd_dev->header.object_prefix = NULL; - return ret; } @@ -6077,8 +5943,6 @@ static int rbd_dev_header_name(struct rbd_device *rbd_dev) /* Record the header object name for this rbd image. */ rbd_assert(rbd_image_format_valid(rbd_dev->image_format)); - - rbd_dev->header_oloc.pool = rbd_dev->layout.pool_id; if (rbd_dev->image_format == 1) ret = ceph_oid_aprintf(&rbd_dev->header_oid, GFP_KERNEL, "%s%s", spec->image_name, RBD_SUFFIX); @@ -6471,27 +6335,16 @@ static int rbd_slab_init(void) if (!rbd_obj_request_cache) goto out_err; - rbd_assert(!rbd_segment_name_cache); - rbd_segment_name_cache = kmem_cache_create("rbd_segment_name", - CEPH_MAX_OID_NAME_LEN + 1, 1, 0, NULL); - if (rbd_segment_name_cache) - return 0; -out_err: - kmem_cache_destroy(rbd_obj_request_cache); - rbd_obj_request_cache = NULL; + return 0; +out_err: kmem_cache_destroy(rbd_img_request_cache); rbd_img_request_cache = NULL; - return -ENOMEM; } static void rbd_slab_exit(void) { - rbd_assert(rbd_segment_name_cache); - kmem_cache_destroy(rbd_segment_name_cache); - rbd_segment_name_cache = NULL; - rbd_assert(rbd_obj_request_cache); kmem_cache_destroy(rbd_obj_request_cache); rbd_obj_request_cache = NULL; diff --git a/drivers/block/rbd_types.h b/drivers/block/rbd_types.h index 94f367db27b0..62ff50d3e7a6 100644 --- a/drivers/block/rbd_types.h +++ b/drivers/block/rbd_types.h @@ -25,8 +25,8 @@ */ #define RBD_HEADER_PREFIX "rbd_header." -#define RBD_DATA_PREFIX "rbd_data." #define RBD_ID_PREFIX "rbd_id." +#define RBD_V2_DATA_FORMAT "%s.%016llx" #define RBD_LOCK_NAME "rbd_lock" #define RBD_LOCK_TAG "internal" @@ -42,13 +42,14 @@ enum rbd_notify_op { /* * For format version 1, rbd image 'foo' consists of objects * foo.rbd - image metadata - * rb.<idhi>.<idlo>.00000000 - * rb.<idhi>.<idlo>.00000001 + * rb.<idhi>.<idlo>.<extra>.000000000000 + * rb.<idhi>.<idlo>.<extra>.000000000001 * ... - data * There is no notion of a persistent image id in rbd format 1. */ #define RBD_SUFFIX ".rbd" +#define RBD_V1_DATA_FORMAT "%s.%012llx" #define RBD_DIRECTORY "rbd_directory" #define RBD_INFO "rbd_info" @@ -57,9 +58,6 @@ enum rbd_notify_op { #define RBD_MIN_OBJ_ORDER 16 #define RBD_MAX_OBJ_ORDER 30 -#define RBD_COMP_NONE 0 -#define RBD_CRYPT_NONE 0 - #define RBD_HEADER_TEXT "<<< Rados Block Device Image >>>\n" #define RBD_HEADER_SIGNATURE "RBD" #define RBD_HEADER_VERSION "001.005" diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig index 7f816655cbbf..90f3edffb067 100644 --- a/drivers/char/ipmi/Kconfig +++ b/drivers/char/ipmi/Kconfig @@ -78,7 +78,8 @@ config IPMI_POWEROFF endif # IPMI_HANDLER config ASPEED_BT_IPMI_BMC - depends on ARCH_ASPEED + depends on ARCH_ASPEED || COMPILE_TEST + depends on REGMAP && REGMAP_MMIO && MFD_SYSCON tristate "BT IPMI bmc driver" help Provides a driver for the BT (Block Transfer) IPMI interface diff --git a/drivers/char/ipmi/bt-bmc.c b/drivers/char/ipmi/bt-bmc.c index fc9e8891eae3..d6f5d9eb102d 100644 --- a/drivers/char/ipmi/bt-bmc.c +++ b/drivers/char/ipmi/bt-bmc.c @@ -12,10 +12,13 @@ #include <linux/errno.h> #include <linux/interrupt.h> #include <linux/io.h> +#include <linux/mfd/syscon.h> #include <linux/miscdevice.h> #include <linux/module.h> +#include <linux/of.h> #include <linux/platform_device.h> #include <linux/poll.h> +#include <linux/regmap.h> #include <linux/sched.h> #include <linux/timer.h> @@ -60,7 +63,8 @@ struct bt_bmc { struct device dev; struct miscdevice miscdev; - void __iomem *base; + struct regmap *map; + int offset; int irq; wait_queue_head_t queue; struct timer_list poll_timer; @@ -69,14 +73,29 @@ struct bt_bmc { static atomic_t open_count = ATOMIC_INIT(0); +static const struct regmap_config bt_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = 4, +}; + static u8 bt_inb(struct bt_bmc *bt_bmc, int reg) { - return ioread8(bt_bmc->base + reg); + uint32_t val = 0; + int rc; + + rc = regmap_read(bt_bmc->map, bt_bmc->offset + reg, &val); + WARN(rc != 0, "regmap_read() failed: %d\n", rc); + + return rc == 0 ? (u8) val : 0; } static void bt_outb(struct bt_bmc *bt_bmc, u8 data, int reg) { - iowrite8(data, bt_bmc->base + reg); + int rc; + + rc = regmap_write(bt_bmc->map, bt_bmc->offset + reg, data); + WARN(rc != 0, "regmap_write() failed: %d\n", rc); } static void clr_rd_ptr(struct bt_bmc *bt_bmc) @@ -367,14 +386,18 @@ static irqreturn_t bt_bmc_irq(int irq, void *arg) { struct bt_bmc *bt_bmc = arg; u32 reg; + int rc; + + rc = regmap_read(bt_bmc->map, bt_bmc->offset + BT_CR2, ®); + if (rc) + return IRQ_NONE; - reg = ioread32(bt_bmc->base + BT_CR2); reg &= BT_CR2_IRQ_H2B | BT_CR2_IRQ_HBUSY; if (!reg) return IRQ_NONE; /* ack pending IRQs */ - iowrite32(reg, bt_bmc->base + BT_CR2); + regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR2, reg); wake_up(&bt_bmc->queue); return IRQ_HANDLED; @@ -384,7 +407,6 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc, struct platform_device *pdev) { struct device *dev = &pdev->dev; - u32 reg; int rc; bt_bmc->irq = platform_get_irq(pdev, 0); @@ -405,18 +427,17 @@ static int bt_bmc_config_irq(struct bt_bmc *bt_bmc, * will be cleared (along with B2H) when we can write the next * message to the BT buffer */ - reg = ioread32(bt_bmc->base + BT_CR1); - reg |= BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY; - iowrite32(reg, bt_bmc->base + BT_CR1); + rc = regmap_update_bits(bt_bmc->map, bt_bmc->offset + BT_CR1, + (BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY), + (BT_CR1_IRQ_H2B | BT_CR1_IRQ_HBUSY)); - return 0; + return rc; } static int bt_bmc_probe(struct platform_device *pdev) { struct bt_bmc *bt_bmc; struct device *dev; - struct resource *res; int rc; if (!pdev || !pdev->dev.of_node) @@ -431,10 +452,27 @@ static int bt_bmc_probe(struct platform_device *pdev) dev_set_drvdata(&pdev->dev, bt_bmc); - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - bt_bmc->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(bt_bmc->base)) - return PTR_ERR(bt_bmc->base); + bt_bmc->map = syscon_node_to_regmap(pdev->dev.parent->of_node); + if (IS_ERR(bt_bmc->map)) { + struct resource *res; + void __iomem *base; + + /* + * Assume it's not the MFD-based devicetree description, in + * which case generate a regmap ourselves + */ + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(base)) + return PTR_ERR(base); + + bt_bmc->map = devm_regmap_init_mmio(dev, base, &bt_regmap_cfg); + bt_bmc->offset = 0; + } else { + rc = of_property_read_u32(dev->of_node, "reg", &bt_bmc->offset); + if (rc) + return rc; + } mutex_init(&bt_bmc->mutex); init_waitqueue_head(&bt_bmc->queue); @@ -461,12 +499,12 @@ static int bt_bmc_probe(struct platform_device *pdev) add_timer(&bt_bmc->poll_timer); } - iowrite32((BT_IO_BASE << BT_CR0_IO_BASE) | - (BT_IRQ << BT_CR0_IRQ) | - BT_CR0_EN_CLR_SLV_RDP | - BT_CR0_EN_CLR_SLV_WRP | - BT_CR0_ENABLE_IBT, - bt_bmc->base + BT_CR0); + regmap_write(bt_bmc->map, bt_bmc->offset + BT_CR0, + (BT_IO_BASE << BT_CR0_IO_BASE) | + (BT_IRQ << BT_CR0_IRQ) | + BT_CR0_EN_CLR_SLV_RDP | + BT_CR0_EN_CLR_SLV_WRP | + BT_CR0_ENABLE_IBT); clr_b_busy(bt_bmc); diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c index a21407de46ae..f45119c5337d 100644 --- a/drivers/char/ipmi/ipmi_devintf.c +++ b/drivers/char/ipmi/ipmi_devintf.c @@ -108,7 +108,7 @@ static int ipmi_fasync(int fd, struct file *file, int on) return (result); } -static struct ipmi_user_hndl ipmi_hndlrs = +static const struct ipmi_user_hndl ipmi_hndlrs = { .ipmi_recv_hndl = file_receive_handler, }; diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c index 92e53acf2cd2..9f699951b75a 100644 --- a/drivers/char/ipmi/ipmi_msghandler.c +++ b/drivers/char/ipmi/ipmi_msghandler.c @@ -102,7 +102,7 @@ struct ipmi_user { struct kref refcount; /* The upper layer that handles receive messages. */ - struct ipmi_user_hndl *handler; + const struct ipmi_user_hndl *handler; void *handler_data; /* The interface this user is bound to. */ @@ -919,7 +919,7 @@ static int intf_err_seq(ipmi_smi_t intf, int ipmi_create_user(unsigned int if_num, - struct ipmi_user_hndl *handler, + const struct ipmi_user_hndl *handler, void *handler_data, ipmi_user_t *user) { diff --git a/drivers/char/ipmi/ipmi_powernv.c b/drivers/char/ipmi/ipmi_powernv.c index 6e658aa114f1..b338a4becbf8 100644 --- a/drivers/char/ipmi/ipmi_powernv.c +++ b/drivers/char/ipmi/ipmi_powernv.c @@ -196,7 +196,7 @@ static void ipmi_powernv_poll(void *send_info) ipmi_powernv_recv(smi); } -static struct ipmi_smi_handlers ipmi_powernv_smi_handlers = { +static const struct ipmi_smi_handlers ipmi_powernv_smi_handlers = { .owner = THIS_MODULE, .start_processing = ipmi_powernv_start_processing, .sender = ipmi_powernv_send, diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c index 4035495f3a86..30b9e83bf1bf 100644 --- a/drivers/char/ipmi/ipmi_watchdog.c +++ b/drivers/char/ipmi/ipmi_watchdog.c @@ -985,7 +985,7 @@ static void ipmi_wdog_pretimeout_handler(void *handler_data) pretimeout_since_last_heartbeat = 1; } -static struct ipmi_user_hndl ipmi_hndlrs = { +static const struct ipmi_user_hndl ipmi_hndlrs = { .ipmi_recv_hndl = ipmi_wdog_msg_handler, .ipmi_watchdog_pretimeout = ipmi_wdog_pretimeout_handler }; diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c index e051fc8aa7d7..cd53771b9ae7 100644 --- a/drivers/char/pcmcia/cm4000_cs.c +++ b/drivers/char/pcmcia/cm4000_cs.c @@ -655,7 +655,7 @@ static void terminate_monitor(struct cm4000_dev *dev) * monitor the card every 50msec. as a side-effect, retrieve the * atr once a card is inserted. another side-effect of retrieving the * atr is that the card will be powered on, so there is no need to - * power on the card explictely from the application: the driver + * power on the card explicitly from the application: the driver * is already doing that for you. */ @@ -1037,7 +1037,7 @@ release_io: clear_bit(LOCK_IO, &dev->flags); wake_up_interruptible(&dev->ioq); - DEBUGP(2, dev, "<- cmm_read returns: rc = %Zi\n", + DEBUGP(2, dev, "<- cmm_read returns: rc = %zi\n", (rc < 0 ? rc : count)); return rc < 0 ? rc : count; } diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c index d7123259143e..d4dbd8d8e524 100644 --- a/drivers/char/pcmcia/cm4040_cs.c +++ b/drivers/char/pcmcia/cm4040_cs.c @@ -331,7 +331,7 @@ static ssize_t cm4040_write(struct file *filp, const char __user *buf, } if ((count < 5) || (count > READ_WRITE_BUFFER_SIZE)) { - DEBUGP(2, dev, "<- cm4040_write buffersize=%Zd < 5\n", count); + DEBUGP(2, dev, "<- cm4040_write buffersize=%zd < 5\n", count); return -EIO; } diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index 4fa7fcd8af36..f4f866ee54bc 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c @@ -603,7 +603,7 @@ static void sonypi_type3_srs(void) u16 v16; u8 v8; - /* This model type uses the same initialiazation of + /* This model type uses the same initialization of * the embedded controller as the type2 models. */ sonypi_type2_srs(); diff --git a/drivers/crypto/Kconfig b/drivers/crypto/Kconfig index 2cac445b02fd..0b49dbc423e2 100644 --- a/drivers/crypto/Kconfig +++ b/drivers/crypto/Kconfig @@ -62,19 +62,32 @@ config CRYPTO_DEV_GEODE will be called geode-aes. config ZCRYPT - tristate "Support for PCI-attached cryptographic adapters" + tristate "Support for s390 cryptographic adapters" depends on S390 select HW_RANDOM help - Select this option if you want to use a PCI-attached cryptographic - adapter like: - + PCI Cryptographic Accelerator (PCICA) - + PCI Cryptographic Coprocessor (PCICC) + Select this option if you want to enable support for + s390 cryptographic adapters like: + PCI-X Cryptographic Coprocessor (PCIXCC) - + Crypto Express2 Coprocessor (CEX2C) - + Crypto Express2 Accelerator (CEX2A) - + Crypto Express3 Coprocessor (CEX3C) - + Crypto Express3 Accelerator (CEX3A) + + Crypto Express 2,3,4 or 5 Coprocessor (CEXxC) + + Crypto Express 2,3,4 or 5 Accelerator (CEXxA) + + Crypto Express 4 or 5 EP11 Coprocessor (CEXxP) + +config PKEY + tristate "Kernel API for protected key handling" + depends on S390 + depends on ZCRYPT + help + With this option enabled the pkey kernel module provides an API + for creation and handling of protected keys. Other parts of the + kernel or userspace applications may use these functions. + + Select this option if you want to enable the kernel and userspace + API for proteced key handling. + + Please note that creation of protected keys from secure keys + requires to have at least one CEX card in coprocessor mode + available at runtime. config CRYPTO_SHA1_S390 tristate "SHA1 digest algorithm" @@ -124,6 +137,7 @@ config CRYPTO_AES_S390 depends on S390 select CRYPTO_ALGAPI select CRYPTO_BLKCIPHER + select PKEY help This is the s390 hardware accelerated implementation of the AES cipher algorithms (FIPS-197). diff --git a/drivers/crypto/caam/ctrl.c b/drivers/crypto/caam/ctrl.c index 579f8263c479..fef39f9f41ee 100644 --- a/drivers/crypto/caam/ctrl.c +++ b/drivers/crypto/caam/ctrl.c @@ -269,7 +269,7 @@ static int deinstantiate_rng(struct device *ctrldev, int state_handle_mask) /* * If the corresponding bit is set, then it means the state * handle was initialized by us, and thus it needs to be - * deintialized as well + * deinitialized as well */ if ((1 << sh_idx) & state_handle_mask) { /* diff --git a/drivers/devfreq/devfreq.c b/drivers/devfreq/devfreq.c index 551a271353d2..dea04871b50d 100644 --- a/drivers/devfreq/devfreq.c +++ b/drivers/devfreq/devfreq.c @@ -1228,7 +1228,7 @@ static int __init devfreq_init(void) subsys_initcall(devfreq_init); /* - * The followings are helper functions for devfreq user device drivers with + * The following are helper functions for devfreq user device drivers with * OPP framework. */ diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 718f832a5c71..0007b792827b 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -325,6 +325,9 @@ static const struct file_operations dma_buf_fops = { .llseek = dma_buf_llseek, .poll = dma_buf_poll, .unlocked_ioctl = dma_buf_ioctl, +#ifdef CONFIG_COMPAT + .compat_ioctl = dma_buf_ioctl, +#endif }; /* diff --git a/drivers/extcon/extcon-rt8973a.c b/drivers/extcon/extcon-rt8973a.c index 3e882aa107e8..eaa355e7d9e4 100644 --- a/drivers/extcon/extcon-rt8973a.c +++ b/drivers/extcon/extcon-rt8973a.c @@ -537,7 +537,7 @@ static void rt8973a_init_dev_type(struct rt8973a_muic_info *info) regmap_update_bits(info->regmap, reg, mask, val); } - /* Check whether RT8973A is auto swithcing mode or not */ + /* Check whether RT8973A is auto switching mode or not */ ret = regmap_read(info->regmap, RT8973A_REG_CONTROL1, &data); if (ret) { dev_err(info->dev, diff --git a/drivers/firewire/core-cdev.c b/drivers/firewire/core-cdev.c index aee149bdf4c0..a301fcf46e88 100644 --- a/drivers/firewire/core-cdev.c +++ b/drivers/firewire/core-cdev.c @@ -1307,8 +1307,7 @@ static void iso_resource_work(struct work_struct *work) */ if (r->todo == ISO_RES_REALLOC && !success && !client->in_shutdown && - idr_find(&client->resource_idr, r->resource.handle)) { - idr_remove(&client->resource_idr, r->resource.handle); + idr_remove(&client->resource_idr, r->resource.handle)) { client_put(client); free = true; } diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c index f9e3aee6a211..7c2eed76011e 100644 --- a/drivers/firewire/core-device.c +++ b/drivers/firewire/core-device.c @@ -1068,7 +1068,7 @@ static void fw_device_init(struct work_struct *work) /* * Transition the device to running state. If it got pulled - * out from under us while we did the intialization work, we + * out from under us while we did the initialization work, we * have to shut down the device again here. Normally, though, * fw_node_event will be responsible for shutting it down when * necessary. We have to use the atomic cmpxchg here to avoid @@ -1231,7 +1231,7 @@ void fw_node_event(struct fw_card *card, struct fw_node *node, int event) break; /* - * Do minimal intialization of the device here, the + * Do minimal initialization of the device here, the * rest will happen in fw_device_init(). * * Attention: A lot of things, even fw_device_get(), diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c index c02db01f6583..0218cea6be4d 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_bo_list.c @@ -70,10 +70,10 @@ static void amdgpu_bo_list_destroy(struct amdgpu_fpriv *fpriv, int id) struct amdgpu_bo_list *list; mutex_lock(&fpriv->bo_list_lock); - list = idr_find(&fpriv->bo_list_handles, id); + list = idr_remove(&fpriv->bo_list_handles, id); if (list) { + /* Another user may have a reference to this list still */ mutex_lock(&list->lock); - idr_remove(&fpriv->bo_list_handles, id); mutex_unlock(&list->lock); amdgpu_bo_list_free(list); } diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index 400c66ba4c6b..cf0500671353 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -135,15 +135,11 @@ static int amdgpu_ctx_free(struct amdgpu_fpriv *fpriv, uint32_t id) struct amdgpu_ctx *ctx; mutex_lock(&mgr->lock); - ctx = idr_find(&mgr->ctx_handles, id); - if (ctx) { - idr_remove(&mgr->ctx_handles, id); + ctx = idr_remove(&mgr->ctx_handles, id); + if (ctx) kref_put(&ctx->refcount, amdgpu_ctx_do_release); - mutex_unlock(&mgr->lock); - return 0; - } mutex_unlock(&mgr->lock); - return -EINVAL; + return ctx ? 0 : -EINVAL; } static int amdgpu_ctx_query(struct amdgpu_device *adev, diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_process.c b/drivers/gpu/drm/amd/amdkfd/kfd_process.c index ef7c8de7060e..ca5f2aa7232d 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_process.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_process.c @@ -262,7 +262,7 @@ static void kfd_process_notifier_release(struct mmu_notifier *mn, * and because the mmu_notifier_unregister function also drop * mm_count we need to take an extra count here. */ - atomic_inc(&p->mm->mm_count); + mmgrab(p->mm); mmu_notifier_unregister_no_release(&p->mmu_notifier, p->mm); mmu_notifier_call_srcu(&p->rcu, &kfd_process_destroy_delayed); } diff --git a/drivers/gpu/drm/amd/include/atombios.h b/drivers/gpu/drm/amd/include/atombios.h index 4a4d3797a6d3..181a2c3c6362 100644 --- a/drivers/gpu/drm/amd/include/atombios.h +++ b/drivers/gpu/drm/amd/include/atombios.h @@ -188,7 +188,7 @@ #define HW_ASSISTED_I2C_STATUS_FAILURE 2 #define HW_ASSISTED_I2C_STATUS_SUCCESS 1 -#pragma pack(1) // BIOS data must use byte aligment +#pragma pack(1) // BIOS data must use byte alignment // Define offset to location of ROM header. #define OFFSET_TO_POINTER_TO_ATOM_ROM_HEADER 0x00000048L @@ -4361,7 +4361,7 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT // GPIO use to control PCIE_VDDC in certain SLT board #define PCIE_VDDC_CONTROL_GPIO_PINID 56 -//from SMU7.x, if ucGPIO_ID=PP_AC_DC_SWITCH_GPIO_PINID in GPIO_LUTTable, AC/DC swithing feature is enable +//from SMU7.x, if ucGPIO_ID=PP_AC_DC_SWITCH_GPIO_PINID in GPIO_LUTTable, AC/DC switching feature is enable #define PP_AC_DC_SWITCH_GPIO_PINID 60 //from SMU7.x, if ucGPIO_ID=VDDC_REGULATOR_VRHOT_GPIO_PINID in GPIO_LUTable, VRHot feature is enable #define VDDC_VRHOT_GPIO_PINID 61 @@ -9180,7 +9180,7 @@ typedef struct _ATOM_POWERPLAY_INFO_V3 /*********************************************************************************/ -#pragma pack() // BIOS data must use byte aligment +#pragma pack() // BIOS data must use byte alignment #pragma pack(1) @@ -9211,7 +9211,7 @@ typedef struct _ATOM_SERVICE_INFO -#pragma pack() // BIOS data must use byte aligment +#pragma pack() // BIOS data must use byte alignment // // AMD ACPI Table diff --git a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h index 26129972f686..80ed65985af8 100644 --- a/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h +++ b/drivers/gpu/drm/amd/powerplay/inc/hardwaremanager.h @@ -89,7 +89,7 @@ enum phm_platform_caps { PHM_PlatformCaps_EnableSideportControl, /* indicates Sideport can be controlled */ PHM_PlatformCaps_VideoPlaybackEEUNotification, /* indicates EEU notification of video start/stop is required */ PHM_PlatformCaps_TurnOffPll_ASPML1, /* PCIE Turn Off PLL in ASPM L1 */ - PHM_PlatformCaps_EnableHTLinkControl, /* indicates HT Link can be controlled by ACPI or CLMC overrided/automated mode. */ + PHM_PlatformCaps_EnableHTLinkControl, /* indicates HT Link can be controlled by ACPI or CLMC overridden/automated mode. */ PHM_PlatformCaps_PerformanceStateOnly, /* indicates only performance power state to be used on current system. */ PHM_PlatformCaps_ExclusiveModeAlwaysHigh, /* In Exclusive (3D) mode always stay in High state. */ PHM_PlatformCaps_DisableMGClockGating, /* to disable Medium Grain Clock Gating or not */ diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c index 93381454bdf7..dc4419ada12c 100644 --- a/drivers/gpu/drm/drm_probe_helper.c +++ b/drivers/gpu/drm/drm_probe_helper.c @@ -220,8 +220,8 @@ drm_connector_detect(struct drm_connector *connector, bool force) * - drm_mode_validate_basic() performs basic sanity checks * - drm_mode_validate_size() filters out modes larger than @maxX and @maxY * (if specified) - * - drm_mode_validate_flag() checks the modes againt basic connector - * capabilites (interlace_allowed,doublescan_allowed,stereo_allowed) + * - drm_mode_validate_flag() checks the modes against basic connector + * capabilities (interlace_allowed,doublescan_allowed,stereo_allowed) * - the optional &drm_connector_helper_funcs.mode_valid helper can perform * driver and/or hardware specific checks * diff --git a/drivers/gpu/drm/i915/i915_gem_render_state.c b/drivers/gpu/drm/i915/i915_gem_render_state.c index b42c81b42487..7032c542a9b1 100644 --- a/drivers/gpu/drm/i915/i915_gem_render_state.c +++ b/drivers/gpu/drm/i915/i915_gem_render_state.c @@ -60,7 +60,7 @@ render_state_get_rodata(const struct intel_engine_cs *engine) * this is sufficient as the null state generator makes the final batch * with two passes to build command and state separately. At this point * the size of both are known and it compacts them by relocating the state - * right after the commands taking care of aligment so we should sufficient + * right after the commands taking care of alignment so we should sufficient * space below them for adding new commands. */ #define OUT_BATCH(batch, i, val) \ diff --git a/drivers/gpu/drm/i915/i915_gem_userptr.c b/drivers/gpu/drm/i915/i915_gem_userptr.c index 6a8fa085b74e..0115989e324a 100644 --- a/drivers/gpu/drm/i915/i915_gem_userptr.c +++ b/drivers/gpu/drm/i915/i915_gem_userptr.c @@ -334,7 +334,7 @@ i915_gem_userptr_init__mm_struct(struct drm_i915_gem_object *obj) mm->i915 = to_i915(obj->base.dev); mm->mm = current->mm; - atomic_inc(¤t->mm->mm_count); + mmgrab(current->mm); mm->mn = NULL; @@ -507,7 +507,7 @@ __i915_gem_userptr_get_pages_worker(struct work_struct *_work) flags |= FOLL_WRITE; ret = -EFAULT; - if (atomic_inc_not_zero(&mm->mm_users)) { + if (mmget_not_zero(mm)) { down_read(&mm->mmap_sem); while (pinned < npages) { ret = get_user_pages_remote diff --git a/drivers/gpu/drm/mga/mga_drv.h b/drivers/gpu/drm/mga/mga_drv.h index d5ce829b3199..45cf363d25ad 100644 --- a/drivers/gpu/drm/mga/mga_drv.h +++ b/drivers/gpu/drm/mga/mga_drv.h @@ -266,7 +266,7 @@ do { \ do { \ if (MGA_VERBOSE) { \ DRM_INFO("BEGIN_DMA(%d)\n", (n)); \ - DRM_INFO(" space=0x%x req=0x%Zx\n", \ + DRM_INFO(" space=0x%x req=0x%zx\n", \ dev_priv->prim.space, (n) * DMA_BLOCK_SIZE); \ } \ prim = dev_priv->prim.start; \ @@ -313,7 +313,7 @@ do { \ #define DMA_WRITE(offset, val) \ do { \ if (MGA_VERBOSE) \ - DRM_INFO(" DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \ + DRM_INFO(" DMA_WRITE( 0x%08x ) at 0x%04zx\n", \ (u32)(val), write + (offset) * sizeof(u32)); \ *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \ } while (0) diff --git a/drivers/gpu/drm/radeon/atombios.h b/drivers/gpu/drm/radeon/atombios.h index ab89eed9ddd9..4b86e8b45009 100644 --- a/drivers/gpu/drm/radeon/atombios.h +++ b/drivers/gpu/drm/radeon/atombios.h @@ -181,7 +181,7 @@ #define HW_ASSISTED_I2C_STATUS_FAILURE 2 #define HW_ASSISTED_I2C_STATUS_SUCCESS 1 -#pragma pack(1) /* BIOS data must use byte aligment */ +#pragma pack(1) /* BIOS data must use byte alignment */ /* Define offset to location of ROM header. */ @@ -3883,7 +3883,7 @@ typedef struct _ATOM_GPIO_PIN_ASSIGNMENT }ATOM_GPIO_PIN_ASSIGNMENT; //ucGPIO_ID pre-define id for multiple usage -//from SMU7.x, if ucGPIO_ID=PP_AC_DC_SWITCH_GPIO_PINID in GPIO_LUTTable, AC/DC swithing feature is enable +//from SMU7.x, if ucGPIO_ID=PP_AC_DC_SWITCH_GPIO_PINID in GPIO_LUTTable, AC/DC switching feature is enable #define PP_AC_DC_SWITCH_GPIO_PINID 60 //from SMU7.x, if ucGPIO_ID=VDDC_REGULATOR_VRHOT_GPIO_PINID in GPIO_LUTable, VRHot feature is enable #define VDDC_VRHOT_GPIO_PINID 61 @@ -7909,7 +7909,7 @@ typedef struct _ATOM_POWERPLAY_INFO_V3 /*********************************************************************************/ -#pragma pack() // BIOS data must use byte aligment +#pragma pack() // BIOS data must use byte alignment // // AMD ACPI Table diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig index ad31b3eb408f..0e4eb845cbb0 100644 --- a/drivers/gpu/drm/rockchip/Kconfig +++ b/drivers/gpu/drm/rockchip/Kconfig @@ -24,6 +24,7 @@ config ROCKCHIP_ANALOGIX_DP config ROCKCHIP_CDN_DP tristate "Rockchip cdn DP" depends on DRM_ROCKCHIP + depends on EXTCON select SND_SOC_HDMI_CODEC if SND_SOC help This selects support for Rockchip SoC specific extensions diff --git a/drivers/gpu/drm/rockchip/cdn-dp-core.c b/drivers/gpu/drm/rockchip/cdn-dp-core.c index 9ab67a670885..fd79a70b8552 100644 --- a/drivers/gpu/drm/rockchip/cdn-dp-core.c +++ b/drivers/gpu/drm/rockchip/cdn-dp-core.c @@ -111,7 +111,7 @@ static int cdn_dp_clk_enable(struct cdn_dp_device *dp) ret = pm_runtime_get_sync(dp->dev); if (ret < 0) { DRM_DEV_ERROR(dp->dev, "cannot get pm runtime %d\n", ret); - goto err_pclk; + goto err_pm_runtime_get; } reset_control_assert(dp->core_rst); @@ -133,6 +133,8 @@ static int cdn_dp_clk_enable(struct cdn_dp_device *dp) return 0; err_set_rate: + pm_runtime_put(dp->dev); +err_pm_runtime_get: clk_disable_unprepare(dp->core_clk); err_core_clk: clk_disable_unprepare(dp->pclk); diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index 541a5887dd6c..d08f26973d0b 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c @@ -199,9 +199,14 @@ static const struct drm_ioctl_desc vmw_ioctls[] = { VMW_IOCTL_DEF(VMW_PRESENT_READBACK, vmw_present_readback_ioctl, DRM_MASTER | DRM_AUTH), + /* + * The permissions of the below ioctl are overridden in + * vmw_generic_ioctl(). We require either + * DRM_MASTER or capable(CAP_SYS_ADMIN). + */ VMW_IOCTL_DEF(VMW_UPDATE_LAYOUT, vmw_kms_update_layout_ioctl, - DRM_MASTER | DRM_CONTROL_ALLOW), + DRM_RENDER_ALLOW), VMW_IOCTL_DEF(VMW_CREATE_SHADER, vmw_shader_define_ioctl, DRM_AUTH | DRM_RENDER_ALLOW), @@ -1123,6 +1128,10 @@ static long vmw_generic_ioctl(struct file *filp, unsigned int cmd, return (long) vmw_execbuf_ioctl(dev, arg, file_priv, _IOC_SIZE(cmd)); + } else if (nr == DRM_COMMAND_BASE + DRM_VMW_UPDATE_LAYOUT) { + if (!drm_is_current_master(file_priv) && + !capable(CAP_SYS_ADMIN)) + return -EACCES; } if (unlikely(ioctl->cmd != cmd)) diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index 1e59a486bba8..59ff4197173a 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h @@ -41,9 +41,9 @@ #include <drm/ttm/ttm_module.h> #include "vmwgfx_fence.h" -#define VMWGFX_DRIVER_DATE "20160210" +#define VMWGFX_DRIVER_DATE "20170221" #define VMWGFX_DRIVER_MAJOR 2 -#define VMWGFX_DRIVER_MINOR 11 +#define VMWGFX_DRIVER_MINOR 12 #define VMWGFX_DRIVER_PATCHLEVEL 0 #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) diff --git a/drivers/gpu/drm/zte/zx_plane.c b/drivers/gpu/drm/zte/zx_plane.c index 1d08ba381098..d646ac931663 100644 --- a/drivers/gpu/drm/zte/zx_plane.c +++ b/drivers/gpu/drm/zte/zx_plane.c @@ -159,7 +159,7 @@ static void zx_vl_rsz_setup(struct zx_plane *zplane, uint32_t format, void __iomem *rsz = zplane->rsz; u32 src_chroma_w = src_w; u32 src_chroma_h = src_h; - u32 fmt; + int fmt; /* Set up source and destination resolution */ zx_writel(rsz + RSZ_SRC_CFG, RSZ_VER(src_h - 1) | RSZ_HOR(src_w - 1)); @@ -203,7 +203,7 @@ static void zx_vl_plane_atomic_update(struct drm_plane *plane, u32 src_x, src_y, src_w, src_h; u32 dst_x, dst_y, dst_w, dst_h; uint32_t format; - u32 fmt; + int fmt; int num_planes; int i; diff --git a/drivers/hid/hid-kye.c b/drivers/hid/hid-kye.c index 0dd1167b2c9b..9c113f62472d 100644 --- a/drivers/hid/hid-kye.c +++ b/drivers/hid/hid-kye.c @@ -487,7 +487,7 @@ static __u8 *kye_consumer_control_fixup(struct hid_device *hdev, __u8 *rdesc, unsigned int *rsize, int offset, const char *device_name) { /* * the fixup that need to be done: - * - change Usage Maximum in the Comsumer Control + * - change Usage Maximum in the Consumer Control * (report ID 3) to a reasonable value */ if (*rsize >= offset + 31 && diff --git a/drivers/hwmon/g762.c b/drivers/hwmon/g762.c index 6dca2fd3d303..6d1208b2b6d2 100644 --- a/drivers/hwmon/g762.c +++ b/drivers/hwmon/g762.c @@ -861,7 +861,7 @@ static ssize_t fan1_pulses_store(struct device *dev, * (i.e. closed or open-loop). * * Following documentation about hwmon's sysfs interface, a pwm1_enable node - * should accept followings: + * should accept the following: * * 0 : no fan speed control (i.e. fan at full speed) * 1 : manual fan speed control enabled (use pwm[1-*]) (open-loop) diff --git a/drivers/ide/ide-acpi.c b/drivers/ide/ide-acpi.c index b6940992a6ff..968038482d2f 100644 --- a/drivers/ide/ide-acpi.c +++ b/drivers/ide/ide-acpi.c @@ -447,7 +447,7 @@ void ide_acpi_get_timing(ide_hwif_t *hwif) memcpy(&hwif->acpidata->gtm, out_obj->buffer.pointer, sizeof(struct GTM_buffer)); - DEBPRINT("_GTM info: ptr: 0x%p, len: 0x%x, exp.len: 0x%Zx\n", + DEBPRINT("_GTM info: ptr: 0x%p, len: 0x%x, exp.len: 0x%zx\n", out_obj->buffer.pointer, out_obj->buffer.length, sizeof(struct GTM_buffer)); diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c index 3c1b7974d66d..d8a552b47718 100644 --- a/drivers/ide/ide-tape.c +++ b/drivers/ide/ide-tape.c @@ -1136,7 +1136,7 @@ static ssize_t idetape_chrdev_read(struct file *file, char __user *buf, ssize_t ret = 0; int rc; - ide_debug_log(IDE_DBG_FUNC, "count %Zd", count); + ide_debug_log(IDE_DBG_FUNC, "count %zd", count); if (tape->chrdev_dir != IDETAPE_DIR_READ) { if (test_bit(ilog2(IDE_AFLAG_DETECT_BS), &drive->atapi_flags)) @@ -1195,7 +1195,7 @@ static ssize_t idetape_chrdev_write(struct file *file, const char __user *buf, if (tape->write_prot) return -EACCES; - ide_debug_log(IDE_DBG_FUNC, "count %Zd", count); + ide_debug_log(IDE_DBG_FUNC, "count %zd", count); /* Initialize write operation */ rc = idetape_init_rw(drive, IDETAPE_DIR_WRITE); diff --git a/drivers/ide/palm_bk3710.c b/drivers/ide/palm_bk3710.c index 46427ea01753..157f2d1fb7e1 100644 --- a/drivers/ide/palm_bk3710.c +++ b/drivers/ide/palm_bk3710.c @@ -300,7 +300,7 @@ static const struct ide_port_ops palm_bk3710_ports_ops = { .cable_detect = palm_bk3710_cable_detect, }; -static struct ide_port_info palm_bk3710_port_info = { +static struct ide_port_info palm_bk3710_port_info __initdata = { .init_dma = palm_bk3710_init_dma, .port_ops = &palm_bk3710_ports_ops, .dma_ops = &sff_dma_ops, diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile index edaae9f9853c..e426ac877d19 100644 --- a/drivers/infiniband/core/Makefile +++ b/drivers/infiniband/core/Makefile @@ -13,6 +13,7 @@ ib_core-y := packer.o ud_header.o verbs.o cq.o rw.o sysfs.o \ multicast.o mad.o smi.o agent.o mad_rmpp.o ib_core-$(CONFIG_INFINIBAND_USER_MEM) += umem.o ib_core-$(CONFIG_INFINIBAND_ON_DEMAND_PAGING) += umem_odp.o umem_rbtree.o +ib_core-$(CONFIG_CGROUP_RDMA) += cgroup.o ib_cm-y := cm.o diff --git a/drivers/infiniband/core/cgroup.c b/drivers/infiniband/core/cgroup.c new file mode 100644 index 000000000000..126ac5f99db7 --- /dev/null +++ b/drivers/infiniband/core/cgroup.c @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2016 Parav Pandit <pandit.parav@gmail.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope 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. + */ + +#include "core_priv.h" + +/** + * ib_device_register_rdmacg - register with rdma cgroup. + * @device: device to register to participate in resource + * accounting by rdma cgroup. + * + * Register with the rdma cgroup. Should be called before + * exposing rdma device to user space applications to avoid + * resource accounting leak. + * Returns 0 on success or otherwise failure code. + */ +int ib_device_register_rdmacg(struct ib_device *device) +{ + device->cg_device.name = device->name; + return rdmacg_register_device(&device->cg_device); +} + +/** + * ib_device_unregister_rdmacg - unregister with rdma cgroup. + * @device: device to unregister. + * + * Unregister with the rdma cgroup. Should be called after + * all the resources are deallocated, and after a stage when any + * other resource allocation by user application cannot be done + * for this device to avoid any leak in accounting. + */ +void ib_device_unregister_rdmacg(struct ib_device *device) +{ + rdmacg_unregister_device(&device->cg_device); +} + +int ib_rdmacg_try_charge(struct ib_rdmacg_object *cg_obj, + struct ib_device *device, + enum rdmacg_resource_type resource_index) +{ + return rdmacg_try_charge(&cg_obj->cg, &device->cg_device, + resource_index); +} +EXPORT_SYMBOL(ib_rdmacg_try_charge); + +void ib_rdmacg_uncharge(struct ib_rdmacg_object *cg_obj, + struct ib_device *device, + enum rdmacg_resource_type resource_index) +{ + rdmacg_uncharge(cg_obj->cg, &device->cg_device, + resource_index); +} +EXPORT_SYMBOL(ib_rdmacg_uncharge); diff --git a/drivers/infiniband/core/core_priv.h b/drivers/infiniband/core/core_priv.h index 912ab4cd6eae..cb7d372e4bdf 100644 --- a/drivers/infiniband/core/core_priv.h +++ b/drivers/infiniband/core/core_priv.h @@ -35,6 +35,7 @@ #include <linux/list.h> #include <linux/spinlock.h> +#include <linux/cgroup_rdma.h> #include <rdma/ib_verbs.h> @@ -124,6 +125,35 @@ int ib_cache_setup_one(struct ib_device *device); void ib_cache_cleanup_one(struct ib_device *device); void ib_cache_release_one(struct ib_device *device); +#ifdef CONFIG_CGROUP_RDMA +int ib_device_register_rdmacg(struct ib_device *device); +void ib_device_unregister_rdmacg(struct ib_device *device); + +int ib_rdmacg_try_charge(struct ib_rdmacg_object *cg_obj, + struct ib_device *device, + enum rdmacg_resource_type resource_index); + +void ib_rdmacg_uncharge(struct ib_rdmacg_object *cg_obj, + struct ib_device *device, + enum rdmacg_resource_type resource_index); +#else +static inline int ib_device_register_rdmacg(struct ib_device *device) +{ return 0; } + +static inline void ib_device_unregister_rdmacg(struct ib_device *device) +{ } + +static inline int ib_rdmacg_try_charge(struct ib_rdmacg_object *cg_obj, + struct ib_device *device, + enum rdmacg_resource_type resource_index) +{ return 0; } + +static inline void ib_rdmacg_uncharge(struct ib_rdmacg_object *cg_obj, + struct ib_device *device, + enum rdmacg_resource_type resource_index) +{ } +#endif + static inline bool rdma_is_upper_dev_rcu(struct net_device *dev, struct net_device *upper) { diff --git a/drivers/infiniband/core/device.c b/drivers/infiniband/core/device.c index a63e8400ea3b..593d2ce6ec7c 100644 --- a/drivers/infiniband/core/device.c +++ b/drivers/infiniband/core/device.c @@ -369,10 +369,18 @@ int ib_register_device(struct ib_device *device, goto out; } + ret = ib_device_register_rdmacg(device); + if (ret) { + pr_warn("Couldn't register device with rdma cgroup\n"); + ib_cache_cleanup_one(device); + goto out; + } + memset(&device->attrs, 0, sizeof(device->attrs)); ret = device->query_device(device, &device->attrs, &uhw); if (ret) { pr_warn("Couldn't query the device attributes\n"); + ib_device_unregister_rdmacg(device); ib_cache_cleanup_one(device); goto out; } @@ -381,6 +389,7 @@ int ib_register_device(struct ib_device *device, if (ret) { pr_warn("Couldn't register device %s with driver model\n", device->name); + ib_device_unregister_rdmacg(device); ib_cache_cleanup_one(device); goto out; } @@ -430,6 +439,7 @@ void ib_unregister_device(struct ib_device *device) mutex_unlock(&device_mutex); + ib_device_unregister_rdmacg(device); ib_device_unregister_sysfs(device); ib_cache_cleanup_one(device); diff --git a/drivers/infiniband/core/uverbs_cmd.c b/drivers/infiniband/core/uverbs_cmd.c index b4b395a054ac..7b7a76e1279a 100644 --- a/drivers/infiniband/core/uverbs_cmd.c +++ b/drivers/infiniband/core/uverbs_cmd.c @@ -316,6 +316,7 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, struct ib_udata udata; struct ib_ucontext *ucontext; struct file *filp; + struct ib_rdmacg_object cg_obj; int ret; if (out_len < sizeof resp) @@ -335,13 +336,18 @@ ssize_t ib_uverbs_get_context(struct ib_uverbs_file *file, (unsigned long) cmd.response + sizeof resp, in_len - sizeof cmd, out_len - sizeof resp); + ret = ib_rdmacg_try_charge(&cg_obj, ib_dev, RDMACG_RESOURCE_HCA_HANDLE); + if (ret) + goto err; + ucontext = ib_dev->alloc_ucontext(ib_dev, &udata); if (IS_ERR(ucontext)) { ret = PTR_ERR(ucontext); - goto err; + goto err_alloc; } ucontext->device = ib_dev; + ucontext->cg_obj = cg_obj; INIT_LIST_HEAD(&ucontext->pd_list); INIT_LIST_HEAD(&ucontext->mr_list); INIT_LIST_HEAD(&ucontext->mw_list); @@ -407,6 +413,9 @@ err_free: put_pid(ucontext->tgid); ib_dev->dealloc_ucontext(ucontext); +err_alloc: + ib_rdmacg_uncharge(&cg_obj, ib_dev, RDMACG_RESOURCE_HCA_HANDLE); + err: mutex_unlock(&file->mutex); return ret; @@ -561,6 +570,13 @@ ssize_t ib_uverbs_alloc_pd(struct ib_uverbs_file *file, return -ENOMEM; init_uobj(uobj, 0, file->ucontext, &pd_lock_class); + ret = ib_rdmacg_try_charge(&uobj->cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); + if (ret) { + kfree(uobj); + return ret; + } + down_write(&uobj->mutex); pd = ib_dev->alloc_pd(ib_dev, file->ucontext, &udata); @@ -605,6 +621,7 @@ err_idr: ib_dealloc_pd(pd); err: + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); put_uobj_write(uobj); return ret; } @@ -637,6 +654,8 @@ ssize_t ib_uverbs_dealloc_pd(struct ib_uverbs_file *file, if (ret) goto err_put; + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + uobj->live = 0; put_uobj_write(uobj); @@ -1006,6 +1025,10 @@ ssize_t ib_uverbs_reg_mr(struct ib_uverbs_file *file, goto err_put; } } + ret = ib_rdmacg_try_charge(&uobj->cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); + if (ret) + goto err_charge; mr = pd->device->reg_user_mr(pd, cmd.start, cmd.length, cmd.hca_va, cmd.access_flags, &udata); @@ -1054,6 +1077,9 @@ err_unreg: ib_dereg_mr(mr); err_put: + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + +err_charge: put_pd_read(pd); err_free: @@ -1178,6 +1204,8 @@ ssize_t ib_uverbs_dereg_mr(struct ib_uverbs_file *file, if (ret) return ret; + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + idr_remove_uobj(&ib_uverbs_mr_idr, uobj); mutex_lock(&file->mutex); @@ -1226,6 +1254,11 @@ ssize_t ib_uverbs_alloc_mw(struct ib_uverbs_file *file, in_len - sizeof(cmd) - sizeof(struct ib_uverbs_cmd_hdr), out_len - sizeof(resp)); + ret = ib_rdmacg_try_charge(&uobj->cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); + if (ret) + goto err_charge; + mw = pd->device->alloc_mw(pd, cmd.mw_type, &udata); if (IS_ERR(mw)) { ret = PTR_ERR(mw); @@ -1271,6 +1304,9 @@ err_unalloc: uverbs_dealloc_mw(mw); err_put: + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + +err_charge: put_pd_read(pd); err_free: @@ -1306,6 +1342,8 @@ ssize_t ib_uverbs_dealloc_mw(struct ib_uverbs_file *file, if (ret) return ret; + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + idr_remove_uobj(&ib_uverbs_mw_idr, uobj); mutex_lock(&file->mutex); @@ -1405,6 +1443,11 @@ static struct ib_ucq_object *create_cq(struct ib_uverbs_file *file, if (cmd_sz > offsetof(typeof(*cmd), flags) + sizeof(cmd->flags)) attr.flags = cmd->flags; + ret = ib_rdmacg_try_charge(&obj->uobject.cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); + if (ret) + goto err_charge; + cq = ib_dev->create_cq(ib_dev, &attr, file->ucontext, uhw); if (IS_ERR(cq)) { @@ -1452,6 +1495,10 @@ err_free: ib_destroy_cq(cq); err_file: + ib_rdmacg_uncharge(&obj->uobject.cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); + +err_charge: if (ev_file) ib_uverbs_release_ucq(file, ev_file, obj); @@ -1732,6 +1779,8 @@ ssize_t ib_uverbs_destroy_cq(struct ib_uverbs_file *file, if (ret) return ret; + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + idr_remove_uobj(&ib_uverbs_cq_idr, uobj); mutex_lock(&file->mutex); @@ -1905,6 +1954,11 @@ static int create_qp(struct ib_uverbs_file *file, goto err_put; } + ret = ib_rdmacg_try_charge(&obj->uevent.uobject.cg_obj, device, + RDMACG_RESOURCE_HCA_OBJECT); + if (ret) + goto err_put; + if (cmd->qp_type == IB_QPT_XRC_TGT) qp = ib_create_qp(pd, &attr); else @@ -1912,7 +1966,7 @@ static int create_qp(struct ib_uverbs_file *file, if (IS_ERR(qp)) { ret = PTR_ERR(qp); - goto err_put; + goto err_create; } if (cmd->qp_type != IB_QPT_XRC_TGT) { @@ -1993,6 +2047,10 @@ err_cb: err_destroy: ib_destroy_qp(qp); +err_create: + ib_rdmacg_uncharge(&obj->uevent.uobject.cg_obj, device, + RDMACG_RESOURCE_HCA_OBJECT); + err_put: if (xrcd) put_xrcd_read(xrcd_uobj); @@ -2519,6 +2577,8 @@ ssize_t ib_uverbs_destroy_qp(struct ib_uverbs_file *file, if (ret) return ret; + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + if (obj->uxrcd) atomic_dec(&obj->uxrcd->refcnt); @@ -2970,11 +3030,16 @@ ssize_t ib_uverbs_create_ah(struct ib_uverbs_file *file, memset(&attr.dmac, 0, sizeof(attr.dmac)); memcpy(attr.grh.dgid.raw, cmd.attr.grh.dgid, 16); + ret = ib_rdmacg_try_charge(&uobj->cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); + if (ret) + goto err_charge; + ah = pd->device->create_ah(pd, &attr, &udata); if (IS_ERR(ah)) { ret = PTR_ERR(ah); - goto err_put; + goto err_create; } ah->device = pd->device; @@ -3013,7 +3078,10 @@ err_copy: err_destroy: ib_destroy_ah(ah); -err_put: +err_create: + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + +err_charge: put_pd_read(pd); err: @@ -3047,6 +3115,8 @@ ssize_t ib_uverbs_destroy_ah(struct ib_uverbs_file *file, if (ret) return ret; + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + idr_remove_uobj(&ib_uverbs_ah_idr, uobj); mutex_lock(&file->mutex); @@ -3861,10 +3931,16 @@ int ib_uverbs_ex_create_flow(struct ib_uverbs_file *file, err = -EINVAL; goto err_free; } + + err = ib_rdmacg_try_charge(&uobj->cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); + if (err) + goto err_free; + flow_id = ib_create_flow(qp, flow_attr, IB_FLOW_DOMAIN_USER); if (IS_ERR(flow_id)) { err = PTR_ERR(flow_id); - goto err_free; + goto err_create; } flow_id->uobject = uobj; uobj->object = flow_id; @@ -3897,6 +3973,8 @@ err_copy: idr_remove_uobj(&ib_uverbs_rule_idr, uobj); destroy_flow: ib_destroy_flow(flow_id); +err_create: + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); err_free: kfree(flow_attr); err_put: @@ -3936,8 +4014,11 @@ int ib_uverbs_ex_destroy_flow(struct ib_uverbs_file *file, flow_id = uobj->object; ret = ib_destroy_flow(flow_id); - if (!ret) + if (!ret) { + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); uobj->live = 0; + } put_uobj_write(uobj); @@ -4005,6 +4086,11 @@ static int __uverbs_create_xsrq(struct ib_uverbs_file *file, obj->uevent.events_reported = 0; INIT_LIST_HEAD(&obj->uevent.event_list); + ret = ib_rdmacg_try_charge(&obj->uevent.uobject.cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); + if (ret) + goto err_put_cq; + srq = pd->device->create_srq(pd, &attr, udata); if (IS_ERR(srq)) { ret = PTR_ERR(srq); @@ -4069,6 +4155,8 @@ err_destroy: ib_destroy_srq(srq); err_put: + ib_rdmacg_uncharge(&obj->uevent.uobject.cg_obj, ib_dev, + RDMACG_RESOURCE_HCA_OBJECT); put_pd_read(pd); err_put_cq: @@ -4255,6 +4343,8 @@ ssize_t ib_uverbs_destroy_srq(struct ib_uverbs_file *file, if (ret) return ret; + ib_rdmacg_uncharge(&uobj->cg_obj, ib_dev, RDMACG_RESOURCE_HCA_OBJECT); + if (srq_type == IB_SRQT_XRC) { us = container_of(obj, struct ib_usrq_object, uevent); atomic_dec(&us->uxrcd->refcnt); diff --git a/drivers/infiniband/core/uverbs_main.c b/drivers/infiniband/core/uverbs_main.c index e3fb4b1af1ad..35c788a32e26 100644 --- a/drivers/infiniband/core/uverbs_main.c +++ b/drivers/infiniband/core/uverbs_main.c @@ -51,6 +51,7 @@ #include <rdma/ib.h> #include "uverbs.h" +#include "core_priv.h" MODULE_AUTHOR("Roland Dreier"); MODULE_DESCRIPTION("InfiniBand userspace verbs access"); @@ -237,6 +238,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_ah_idr, uobj); ib_destroy_ah(ah); + ib_rdmacg_uncharge(&uobj->cg_obj, context->device, + RDMACG_RESOURCE_HCA_OBJECT); kfree(uobj); } @@ -246,6 +249,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_mw_idr, uobj); uverbs_dealloc_mw(mw); + ib_rdmacg_uncharge(&uobj->cg_obj, context->device, + RDMACG_RESOURCE_HCA_OBJECT); kfree(uobj); } @@ -254,6 +259,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_rule_idr, uobj); ib_destroy_flow(flow_id); + ib_rdmacg_uncharge(&uobj->cg_obj, context->device, + RDMACG_RESOURCE_HCA_OBJECT); kfree(uobj); } @@ -266,6 +273,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, if (qp == qp->real_qp) ib_uverbs_detach_umcast(qp, uqp); ib_destroy_qp(qp); + ib_rdmacg_uncharge(&uobj->cg_obj, context->device, + RDMACG_RESOURCE_HCA_OBJECT); ib_uverbs_release_uevent(file, &uqp->uevent); kfree(uqp); } @@ -298,6 +307,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_srq_idr, uobj); ib_destroy_srq(srq); + ib_rdmacg_uncharge(&uobj->cg_obj, context->device, + RDMACG_RESOURCE_HCA_OBJECT); ib_uverbs_release_uevent(file, uevent); kfree(uevent); } @@ -310,6 +321,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_cq_idr, uobj); ib_destroy_cq(cq); + ib_rdmacg_uncharge(&uobj->cg_obj, context->device, + RDMACG_RESOURCE_HCA_OBJECT); ib_uverbs_release_ucq(file, ev_file, ucq); kfree(ucq); } @@ -319,6 +332,8 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_mr_idr, uobj); ib_dereg_mr(mr); + ib_rdmacg_uncharge(&uobj->cg_obj, context->device, + RDMACG_RESOURCE_HCA_OBJECT); kfree(uobj); } @@ -339,11 +354,16 @@ static int ib_uverbs_cleanup_ucontext(struct ib_uverbs_file *file, idr_remove_uobj(&ib_uverbs_pd_idr, uobj); ib_dealloc_pd(pd); + ib_rdmacg_uncharge(&uobj->cg_obj, context->device, + RDMACG_RESOURCE_HCA_OBJECT); kfree(uobj); } put_pid(context->tgid); + ib_rdmacg_uncharge(&context->cg_obj, context->device, + RDMACG_RESOURCE_HCA_HANDLE); + return context->device->dealloc_ucontext(context); } diff --git a/drivers/infiniband/hw/hfi1/file_ops.c b/drivers/infiniband/hw/hfi1/file_ops.c index f46033984d07..3b19c16a9e45 100644 --- a/drivers/infiniband/hw/hfi1/file_ops.c +++ b/drivers/infiniband/hw/hfi1/file_ops.c @@ -185,7 +185,7 @@ static int hfi1_file_open(struct inode *inode, struct file *fp) if (fd) { fd->rec_cpu_num = -1; /* no cpu affinity by default */ fd->mm = current->mm; - atomic_inc(&fd->mm->mm_count); + mmgrab(fd->mm); fp->private_data = fd; } else { fp->private_data = NULL; diff --git a/drivers/infiniband/hw/qib/qib_iba6120.c b/drivers/infiniband/hw/qib/qib_iba6120.c index 92399d3ffd15..06de1cbcf67d 100644 --- a/drivers/infiniband/hw/qib/qib_iba6120.c +++ b/drivers/infiniband/hw/qib/qib_iba6120.c @@ -707,7 +707,7 @@ static void qib_6120_clear_freeze(struct qib_devdata *dd) /* disable error interrupts, to avoid confusion */ qib_write_kreg(dd, kr_errmask, 0ULL); - /* also disable interrupts; errormask is sometimes overwriten */ + /* also disable interrupts; errormask is sometimes overwritten */ qib_6120_set_intr_state(dd, 0); qib_cancel_sends(dd->pport); diff --git a/drivers/infiniband/hw/qib/qib_iba7220.c b/drivers/infiniband/hw/qib/qib_iba7220.c index e55e31a69195..55a18384c22d 100644 --- a/drivers/infiniband/hw/qib/qib_iba7220.c +++ b/drivers/infiniband/hw/qib/qib_iba7220.c @@ -1259,7 +1259,7 @@ static void qib_7220_clear_freeze(struct qib_devdata *dd) /* disable error interrupts, to avoid confusion */ qib_write_kreg(dd, kr_errmask, 0ULL); - /* also disable interrupts; errormask is sometimes overwriten */ + /* also disable interrupts; errormask is sometimes overwritten */ qib_7220_set_intr_state(dd, 0); qib_cancel_sends(dd->pport); diff --git a/drivers/infiniband/hw/qib/qib_iba7322.c b/drivers/infiniband/hw/qib/qib_iba7322.c index 9cc97bd42775..12c4208fd701 100644 --- a/drivers/infiniband/hw/qib/qib_iba7322.c +++ b/drivers/infiniband/hw/qib/qib_iba7322.c @@ -2053,7 +2053,7 @@ static void qib_7322_clear_freeze(struct qib_devdata *dd) qib_write_kreg_port(dd->pport + pidx, krp_errmask, 0ULL); - /* also disable interrupts; errormask is sometimes overwriten */ + /* also disable interrupts; errormask is sometimes overwritten */ qib_7322_set_intr_state(dd, 0); /* clear the freeze, and be sure chip saw it */ diff --git a/drivers/infiniband/sw/rdmavt/mad.c b/drivers/infiniband/sw/rdmavt/mad.c index f6e99778d7ca..bba241faca61 100644 --- a/drivers/infiniband/sw/rdmavt/mad.c +++ b/drivers/infiniband/sw/rdmavt/mad.c @@ -74,9 +74,9 @@ int rvt_process_mad(struct ib_device *ibdev, int mad_flags, u8 port_num, u16 *out_mad_pkey_index) { /* - * MAD processing is quite different between hfi1 and qib. Therfore this - * is expected to be provided by the driver. Other drivers in the future - * may chose to implement this but it should not be made into a + * MAD processing is quite different between hfi1 and qib. Therefore + * this is expected to be provided by the driver. Other drivers in the + * future may choose to implement this but it should not be made into a * requirement. */ if (ibport_num_to_idx(ibdev, port_num) < 0) diff --git a/drivers/input/touchscreen/cyttsp4_core.c b/drivers/input/touchscreen/cyttsp4_core.c index 44deca88c579..beaf61ce775b 100644 --- a/drivers/input/touchscreen/cyttsp4_core.c +++ b/drivers/input/touchscreen/cyttsp4_core.c @@ -202,7 +202,7 @@ static int cyttsp4_si_get_cydata(struct cyttsp4 *cd) int rc; si->si_ofs.cydata_size = si->si_ofs.test_ofs - si->si_ofs.cydata_ofs; - dev_dbg(cd->dev, "%s: cydata size: %Zd\n", __func__, + dev_dbg(cd->dev, "%s: cydata size: %zd\n", __func__, si->si_ofs.cydata_size); p = krealloc(si->si_ptrs.cydata, si->si_ofs.cydata_size, GFP_KERNEL); @@ -430,13 +430,13 @@ static int cyttsp4_si_get_opcfg_data(struct cyttsp4 *cd) for (abs = 0; abs < CY_TCH_NUM_ABS; abs++) { dev_dbg(cd->dev, "%s: tch_rec_%s\n", __func__, cyttsp4_tch_abs_string[abs]); - dev_dbg(cd->dev, "%s: ofs =%2Zd\n", __func__, + dev_dbg(cd->dev, "%s: ofs =%2zd\n", __func__, si->si_ofs.tch_abs[abs].ofs); - dev_dbg(cd->dev, "%s: siz =%2Zd\n", __func__, + dev_dbg(cd->dev, "%s: siz =%2zd\n", __func__, si->si_ofs.tch_abs[abs].size); - dev_dbg(cd->dev, "%s: max =%2Zd\n", __func__, + dev_dbg(cd->dev, "%s: max =%2zd\n", __func__, si->si_ofs.tch_abs[abs].max); - dev_dbg(cd->dev, "%s: bofs=%2Zd\n", __func__, + dev_dbg(cd->dev, "%s: bofs=%2zd\n", __func__, si->si_ofs.tch_abs[abs].bofs); } @@ -586,62 +586,62 @@ static int cyttsp4_si_get_op_data_ptrs(struct cyttsp4 *cd) static void cyttsp4_si_put_log_data(struct cyttsp4 *cd) { struct cyttsp4_sysinfo *si = &cd->sysinfo; - dev_dbg(cd->dev, "%s: cydata_ofs =%4Zd siz=%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: cydata_ofs =%4zd siz=%4zd\n", __func__, si->si_ofs.cydata_ofs, si->si_ofs.cydata_size); - dev_dbg(cd->dev, "%s: test_ofs =%4Zd siz=%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: test_ofs =%4zd siz=%4zd\n", __func__, si->si_ofs.test_ofs, si->si_ofs.test_size); - dev_dbg(cd->dev, "%s: pcfg_ofs =%4Zd siz=%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: pcfg_ofs =%4zd siz=%4zd\n", __func__, si->si_ofs.pcfg_ofs, si->si_ofs.pcfg_size); - dev_dbg(cd->dev, "%s: opcfg_ofs =%4Zd siz=%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: opcfg_ofs =%4zd siz=%4zd\n", __func__, si->si_ofs.opcfg_ofs, si->si_ofs.opcfg_size); - dev_dbg(cd->dev, "%s: ddata_ofs =%4Zd siz=%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: ddata_ofs =%4zd siz=%4zd\n", __func__, si->si_ofs.ddata_ofs, si->si_ofs.ddata_size); - dev_dbg(cd->dev, "%s: mdata_ofs =%4Zd siz=%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: mdata_ofs =%4zd siz=%4zd\n", __func__, si->si_ofs.mdata_ofs, si->si_ofs.mdata_size); - dev_dbg(cd->dev, "%s: cmd_ofs =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: cmd_ofs =%4zd\n", __func__, si->si_ofs.cmd_ofs); - dev_dbg(cd->dev, "%s: rep_ofs =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: rep_ofs =%4zd\n", __func__, si->si_ofs.rep_ofs); - dev_dbg(cd->dev, "%s: rep_sz =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: rep_sz =%4zd\n", __func__, si->si_ofs.rep_sz); - dev_dbg(cd->dev, "%s: num_btns =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: num_btns =%4zd\n", __func__, si->si_ofs.num_btns); - dev_dbg(cd->dev, "%s: num_btn_regs =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: num_btn_regs =%4zd\n", __func__, si->si_ofs.num_btn_regs); - dev_dbg(cd->dev, "%s: tt_stat_ofs =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: tt_stat_ofs =%4zd\n", __func__, si->si_ofs.tt_stat_ofs); - dev_dbg(cd->dev, "%s: tch_rec_size =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: tch_rec_size =%4zd\n", __func__, si->si_ofs.tch_rec_size); - dev_dbg(cd->dev, "%s: max_tchs =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: max_tchs =%4zd\n", __func__, si->si_ofs.max_tchs); - dev_dbg(cd->dev, "%s: mode_size =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: mode_size =%4zd\n", __func__, si->si_ofs.mode_size); - dev_dbg(cd->dev, "%s: data_size =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: data_size =%4zd\n", __func__, si->si_ofs.data_size); - dev_dbg(cd->dev, "%s: map_sz =%4Zd\n", __func__, + dev_dbg(cd->dev, "%s: map_sz =%4zd\n", __func__, si->si_ofs.map_sz); - dev_dbg(cd->dev, "%s: btn_rec_size =%2Zd\n", __func__, + dev_dbg(cd->dev, "%s: btn_rec_size =%2zd\n", __func__, si->si_ofs.btn_rec_size); - dev_dbg(cd->dev, "%s: btn_diff_ofs =%2Zd\n", __func__, + dev_dbg(cd->dev, "%s: btn_diff_ofs =%2zd\n", __func__, si->si_ofs.btn_diff_ofs); - dev_dbg(cd->dev, "%s: btn_diff_size =%2Zd\n", __func__, + dev_dbg(cd->dev, "%s: btn_diff_size =%2zd\n", __func__, si->si_ofs.btn_diff_size); - dev_dbg(cd->dev, "%s: max_x = 0x%04ZX (%Zd)\n", __func__, + dev_dbg(cd->dev, "%s: max_x = 0x%04zX (%zd)\n", __func__, si->si_ofs.max_x, si->si_ofs.max_x); - dev_dbg(cd->dev, "%s: x_origin = %Zd (%s)\n", __func__, + dev_dbg(cd->dev, "%s: x_origin = %zd (%s)\n", __func__, si->si_ofs.x_origin, si->si_ofs.x_origin == CY_NORMAL_ORIGIN ? "left corner" : "right corner"); - dev_dbg(cd->dev, "%s: max_y = 0x%04ZX (%Zd)\n", __func__, + dev_dbg(cd->dev, "%s: max_y = 0x%04zX (%zd)\n", __func__, si->si_ofs.max_y, si->si_ofs.max_y); - dev_dbg(cd->dev, "%s: y_origin = %Zd (%s)\n", __func__, + dev_dbg(cd->dev, "%s: y_origin = %zd (%s)\n", __func__, si->si_ofs.y_origin, si->si_ofs.y_origin == CY_NORMAL_ORIGIN ? "upper corner" : "lower corner"); - dev_dbg(cd->dev, "%s: max_p = 0x%04ZX (%Zd)\n", __func__, + dev_dbg(cd->dev, "%s: max_p = 0x%04zX (%zd)\n", __func__, si->si_ofs.max_p, si->si_ofs.max_p); dev_dbg(cd->dev, "%s: xy_mode=%p xy_data=%p\n", __func__, @@ -1000,7 +1000,7 @@ static int cyttsp4_xy_worker(struct cyttsp4 *cd) dev_dbg(dev, "%s: Large area detected\n", __func__); if (num_cur_tch > si->si_ofs.max_tchs) { - dev_err(dev, "%s: too many tch; set to max tch (n=%d c=%Zd)\n", + dev_err(dev, "%s: too many tch; set to max tch (n=%d c=%zd)\n", __func__, num_cur_tch, si->si_ofs.max_tchs); num_cur_tch = si->si_ofs.max_tchs; } diff --git a/drivers/iommu/amd_iommu_init.c b/drivers/iommu/amd_iommu_init.c index 04cdac7ab3e3..6130278c5d71 100644 --- a/drivers/iommu/amd_iommu_init.c +++ b/drivers/iommu/amd_iommu_init.c @@ -1507,7 +1507,7 @@ static ssize_t amd_iommu_show_cap(struct device *dev, struct device_attribute *attr, char *buf) { - struct amd_iommu *iommu = dev_get_drvdata(dev); + struct amd_iommu *iommu = dev_to_amd_iommu(dev); return sprintf(buf, "%x\n", iommu->cap); } static DEVICE_ATTR(cap, S_IRUGO, amd_iommu_show_cap, NULL); @@ -1516,7 +1516,7 @@ static ssize_t amd_iommu_show_features(struct device *dev, struct device_attribute *attr, char *buf) { - struct amd_iommu *iommu = dev_get_drvdata(dev); + struct amd_iommu *iommu = dev_to_amd_iommu(dev); return sprintf(buf, "%llx\n", iommu->features); } static DEVICE_ATTR(features, S_IRUGO, amd_iommu_show_features, NULL); diff --git a/drivers/iommu/amd_iommu_types.h b/drivers/iommu/amd_iommu_types.h index af00f381a7b1..003f3ceb2661 100644 --- a/drivers/iommu/amd_iommu_types.h +++ b/drivers/iommu/amd_iommu_types.h @@ -569,6 +569,11 @@ struct amd_iommu { volatile u64 __aligned(8) cmd_sem; }; +static inline struct amd_iommu *dev_to_amd_iommu(struct device *dev) +{ + return container_of(dev, struct amd_iommu, iommu.dev); +} + #define ACPIHID_UID_LEN 256 #define ACPIHID_HID_LEN 9 diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index a8f7ae0eb7a4..238ad3447712 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -4730,11 +4730,16 @@ static int intel_iommu_cpu_dead(unsigned int cpu) return 0; } +static inline struct intel_iommu *dev_to_intel_iommu(struct device *dev) +{ + return container_of(dev, struct intel_iommu, iommu.dev); +} + static ssize_t intel_iommu_show_version(struct device *dev, struct device_attribute *attr, char *buf) { - struct intel_iommu *iommu = dev_get_drvdata(dev); + struct intel_iommu *iommu = dev_to_intel_iommu(dev); u32 ver = readl(iommu->reg + DMAR_VER_REG); return sprintf(buf, "%d:%d\n", DMAR_VER_MAJOR(ver), DMAR_VER_MINOR(ver)); @@ -4745,7 +4750,7 @@ static ssize_t intel_iommu_show_address(struct device *dev, struct device_attribute *attr, char *buf) { - struct intel_iommu *iommu = dev_get_drvdata(dev); + struct intel_iommu *iommu = dev_to_intel_iommu(dev); return sprintf(buf, "%llx\n", iommu->reg_phys); } static DEVICE_ATTR(address, S_IRUGO, intel_iommu_show_address, NULL); @@ -4754,7 +4759,7 @@ static ssize_t intel_iommu_show_cap(struct device *dev, struct device_attribute *attr, char *buf) { - struct intel_iommu *iommu = dev_get_drvdata(dev); + struct intel_iommu *iommu = dev_to_intel_iommu(dev); return sprintf(buf, "%llx\n", iommu->cap); } static DEVICE_ATTR(cap, S_IRUGO, intel_iommu_show_cap, NULL); @@ -4763,7 +4768,7 @@ static ssize_t intel_iommu_show_ecap(struct device *dev, struct device_attribute *attr, char *buf) { - struct intel_iommu *iommu = dev_get_drvdata(dev); + struct intel_iommu *iommu = dev_to_intel_iommu(dev); return sprintf(buf, "%llx\n", iommu->ecap); } static DEVICE_ATTR(ecap, S_IRUGO, intel_iommu_show_ecap, NULL); @@ -4772,7 +4777,7 @@ static ssize_t intel_iommu_show_ndoms(struct device *dev, struct device_attribute *attr, char *buf) { - struct intel_iommu *iommu = dev_get_drvdata(dev); + struct intel_iommu *iommu = dev_to_intel_iommu(dev); return sprintf(buf, "%ld\n", cap_ndoms(iommu->cap)); } static DEVICE_ATTR(domains_supported, S_IRUGO, intel_iommu_show_ndoms, NULL); @@ -4781,7 +4786,7 @@ static ssize_t intel_iommu_show_ndoms_used(struct device *dev, struct device_attribute *attr, char *buf) { - struct intel_iommu *iommu = dev_get_drvdata(dev); + struct intel_iommu *iommu = dev_to_intel_iommu(dev); return sprintf(buf, "%d\n", bitmap_weight(iommu->domain_ids, cap_ndoms(iommu->cap))); } diff --git a/drivers/iommu/intel-svm.c b/drivers/iommu/intel-svm.c index cb72e0011310..51f2b228723f 100644 --- a/drivers/iommu/intel-svm.c +++ b/drivers/iommu/intel-svm.c @@ -579,7 +579,7 @@ static irqreturn_t prq_event_thread(int irq, void *d) if (!svm->mm) goto bad_req; /* If the mm is already defunct, don't handle faults. */ - if (!atomic_inc_not_zero(&svm->mm->mm_users)) + if (!mmget_not_zero(svm->mm)) goto bad_req; down_read(&svm->mm->mmap_sem); vma = find_extend_vma(svm->mm, address); diff --git a/drivers/isdn/hardware/eicon/debug.c b/drivers/isdn/hardware/eicon/debug.c index 576b7b4a3278..8bc2791bc39c 100644 --- a/drivers/isdn/hardware/eicon/debug.c +++ b/drivers/isdn/hardware/eicon/debug.c @@ -2049,7 +2049,7 @@ static int diva_dbg_cmp_key(const char *ref, const char *key) { /* In case trace filter starts with "C" character then all following characters are interpreted as command. - Followings commands are available: + Following commands are available: - single, trace single call at time, independent from CPN/CiPN */ static int diva_mnt_cmp_nmbr(const char *nmbr) { diff --git a/drivers/isdn/hardware/mISDN/mISDNipac.c b/drivers/isdn/hardware/mISDN/mISDNipac.c index 8d338ba366d0..77dec28ba874 100644 --- a/drivers/isdn/hardware/mISDN/mISDNipac.c +++ b/drivers/isdn/hardware/mISDN/mISDNipac.c @@ -1625,7 +1625,7 @@ mISDNipac_init(struct ipac_hw *ipac, void *hw) ipac->hscx[i].bch.hw = hw; ipac->hscx[i].ip = ipac; /* default values for IOM time slots - * can be overwriten by card */ + * can be overwritten by card */ ipac->hscx[i].slot = (i == 0) ? 0x2f : 0x03; } diff --git a/drivers/isdn/mISDN/dsp_core.c b/drivers/isdn/mISDN/dsp_core.c index 0222b1a35a2d..9b85295aa657 100644 --- a/drivers/isdn/mISDN/dsp_core.c +++ b/drivers/isdn/mISDN/dsp_core.c @@ -115,7 +115,7 @@ * * The CMX has special functions for conferences with one, two and more * members. It will allow different types of data flow. Receive and transmit - * data to/form upper layer may be swithed on/off individually without losing + * data to/form upper layer may be switched on/off individually without losing * features of CMX, Tones and DTMF. * * Echo Cancellation: Sometimes we like to cancel echo from the interface. diff --git a/drivers/media/dvb-core/dvb_ringbuffer.h b/drivers/media/dvb-core/dvb_ringbuffer.h index bbe94873d44d..8ed6bcc3a56e 100644 --- a/drivers/media/dvb-core/dvb_ringbuffer.h +++ b/drivers/media/dvb-core/dvb_ringbuffer.h @@ -136,7 +136,7 @@ extern void dvb_ringbuffer_flush_spinlock_wakeup(struct dvb_ringbuffer *rbuf); } /** - * dvb_ringbuffer_read_user - Reads a buffer into an user pointer + * dvb_ringbuffer_read_user - Reads a buffer into a user pointer * * @rbuf: pointer to struct dvb_ringbuffer * @buf: pointer to the buffer where the data will be stored @@ -193,7 +193,7 @@ extern ssize_t dvb_ringbuffer_write(struct dvb_ringbuffer *rbuf, const u8 *buf, size_t len); /** - * dvb_ringbuffer_write_user - Writes a buffer received via an user pointer + * dvb_ringbuffer_write_user - Writes a buffer received via a user pointer * * @rbuf: pointer to struct dvb_ringbuffer * @buf: pointer to the buffer where the data will be read diff --git a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h index 9076bf21cc8a..7a681d8202c7 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drx_driver.h +++ b/drivers/media/dvb-frontends/drx39xyj/drx_driver.h @@ -1317,9 +1317,9 @@ struct drx_version_list { DRX_MPEG_STR_WIDTH_8 }; -/* CTRL CFG MPEG ouput */ +/* CTRL CFG MPEG output */ /** -* \struct struct drx_cfg_mpeg_output * \brief Configuartion parameters for MPEG output control. +* \struct struct drx_cfg_mpeg_output * \brief Configuration parameters for MPEG output control. * * Used by DRX_CFG_MPEG_OUTPUT, in combination with DRX_CTRL_SET_CFG and * DRX_CTRL_GET_CFG. diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.c b/drivers/media/dvb-frontends/drx39xyj/drxj.c index f1c3e3b09b65..daeaf965dd56 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.c +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.c @@ -601,7 +601,7 @@ static struct drxj_data drxj_data_g = { 0, /* hi_cfg_wake_up_key */ 0, /* hi_cfg_ctrl */ 0, /* HICfgTimeout */ - /* UIO configuartion */ + /* UIO configuration */ DRX_UIO_MODE_DISABLE, /* uio_sma_rx_mode */ DRX_UIO_MODE_DISABLE, /* uio_sma_tx_mode */ DRX_UIO_MODE_DISABLE, /* uioASELMode */ @@ -619,7 +619,7 @@ static struct drxj_data drxj_data_g = { /* false, * flagHDevSet */ /* (u16) 0xFFF, * rdsLastCount */ - /* ATV configuartion */ + /* ATV configuration */ 0UL, /* flags cfg changes */ /* shadow of ATV_TOP_EQU0__A */ {-5, @@ -3352,7 +3352,7 @@ rw_error: /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ -/* miscellaneous configuartions - begin */ +/* miscellaneous configurations - begin */ /*----------------------------------------------------------------------------*/ /** @@ -3515,7 +3515,7 @@ rw_error: } /*----------------------------------------------------------------------------*/ -/* miscellaneous configuartions - end */ +/* miscellaneous configurations - end */ /*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/ @@ -10952,7 +10952,7 @@ rw_error: static void drxj_reset_mode(struct drxj_data *ext_attr) { - /* Initialize default AFE configuartion for QAM */ + /* Initialize default AFE configuration for QAM */ if (ext_attr->has_lna) { /* IF AGC off, PGA active */ #ifndef DRXJ_VSB_ONLY @@ -10996,7 +10996,7 @@ static void drxj_reset_mode(struct drxj_data *ext_attr) ext_attr->qam_pre_saw_cfg.reference = 0x07; ext_attr->qam_pre_saw_cfg.use_pre_saw = true; #endif - /* Initialize default AFE configuartion for VSB */ + /* Initialize default AFE configuration for VSB */ ext_attr->vsb_rf_agc_cfg.standard = DRX_STANDARD_8VSB; ext_attr->vsb_rf_agc_cfg.ctrl_mode = DRX_AGC_CTRL_AUTO; ext_attr->vsb_rf_agc_cfg.min_output_level = 0; @@ -11072,9 +11072,9 @@ ctrl_power_mode(struct drx_demod_instance *demod, enum drx_power_mode *mode) } if ((*mode == DRX_POWER_UP)) { - /* Restore analog & pin configuartion */ + /* Restore analog & pin configuration */ - /* Initialize default AFE configuartion for VSB */ + /* Initialize default AFE configuration for VSB */ drxj_reset_mode(ext_attr); } else { /* Power down to requested mode */ diff --git a/drivers/media/dvb-frontends/drx39xyj/drxj.h b/drivers/media/dvb-frontends/drx39xyj/drxj.h index 55ad535197d2..6c5b8f78f9f6 100644 --- a/drivers/media/dvb-frontends/drx39xyj/drxj.h +++ b/drivers/media/dvb-frontends/drx39xyj/drxj.h @@ -447,7 +447,7 @@ struct drxj_cfg_atv_output { u16 hi_cfg_ctrl; /**< HI Configure() parameter 5 */ u16 hi_cfg_transmit; /**< HI Configure() parameter 6 */ - /* UIO configuartion */ + /* UIO configuration */ enum drxuio_mode uio_sma_rx_mode;/**< current mode of SmaRx pin */ enum drxuio_mode uio_sma_tx_mode;/**< current mode of SmaTx pin */ enum drxuio_mode uio_gpio_mode; /**< current mode of ASEL pin */ @@ -459,7 +459,7 @@ struct drxj_cfg_atv_output { /* IQM RC frequecy shift */ u32 iqm_rc_rate_ofs; /**< frequency shifter setting after setchannel */ - /* ATV configuartion */ + /* ATV configuration */ u32 atv_cfg_changed_flags; /**< flag: flags cfg changes */ s16 atv_top_equ0[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU0__A */ s16 atv_top_equ1[DRXJ_COEF_IDX_MAX]; /**< shadow of ATV_TOP_EQU1__A */ diff --git a/drivers/media/dvb-frontends/drxk_hard.c b/drivers/media/dvb-frontends/drxk_hard.c index 15d2cac588b1..7e1bbbaad625 100644 --- a/drivers/media/dvb-frontends/drxk_hard.c +++ b/drivers/media/dvb-frontends/drxk_hard.c @@ -1626,7 +1626,7 @@ static int ctrl_power_mode(struct drxk_state *state, enum drx_power_mode *mode) } if (*mode == DRX_POWER_UP) { - /* Restore analog & pin configuartion */ + /* Restore analog & pin configuration */ } else { /* Power down to requested mode */ /* Backup some register settings */ diff --git a/drivers/media/dvb-frontends/helene.c b/drivers/media/dvb-frontends/helene.c index ef35c2b30ea3..4bf5a551ba40 100644 --- a/drivers/media/dvb-frontends/helene.c +++ b/drivers/media/dvb-frontends/helene.c @@ -309,7 +309,7 @@ static int helene_write_regs(struct helene_priv *priv, if (len + 1 > sizeof(buf)) { dev_warn(&priv->i2c->dev, - "wr reg=%04x: len=%d vs %Zu is too big!\n", + "wr reg=%04x: len=%d vs %zu is too big!\n", reg, len + 1, sizeof(buf)); return -E2BIG; } diff --git a/drivers/media/dvb-frontends/or51132.c b/drivers/media/dvb-frontends/or51132.c index 4b67d7e0116d..62aa00767015 100644 --- a/drivers/media/dvb-frontends/or51132.c +++ b/drivers/media/dvb-frontends/or51132.c @@ -133,7 +133,7 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware u32 firmwareAsize, firmwareBsize; int i,ret; - dprintk("Firmware is %Zd bytes\n",fw->size); + dprintk("Firmware is %zd bytes\n",fw->size); /* Get size of firmware A and B */ firmwareAsize = le32_to_cpu(*((__le32*)fw->data)); diff --git a/drivers/media/dvb-frontends/tda10048.c b/drivers/media/dvb-frontends/tda10048.c index 92ab34c3e0be..143b39b5f6c9 100644 --- a/drivers/media/dvb-frontends/tda10048.c +++ b/drivers/media/dvb-frontends/tda10048.c @@ -499,7 +499,7 @@ static int tda10048_firmware_upload(struct dvb_frontend *fe) __func__); return -EIO; } else { - printk(KERN_INFO "%s: firmware read %Zu bytes.\n", + printk(KERN_INFO "%s: firmware read %zu bytes.\n", __func__, fw->size); ret = 0; diff --git a/drivers/media/i2c/adv7183_regs.h b/drivers/media/i2c/adv7183_regs.h index 843d4998435e..4ade89d33d62 100644 --- a/drivers/media/i2c/adv7183_regs.h +++ b/drivers/media/i2c/adv7183_regs.h @@ -83,7 +83,7 @@ #define ADV7183_LETTERBOX_3 0x9D /* Letterbox 3 */ #define ADV7183_CRC_EN 0xB2 /* CRC enable */ #define ADV7183_ADC_SWITCH_1 0xC3 /* ADC switch 1 */ -#define ADV7183_ADC_SWITCH_2 0xC4 /* ADC swithc 2 */ +#define ADV7183_ADC_SWITCH_2 0xC4 /* ADC switch 2 */ #define ADV7183_LETTERBOX_CTRL_1 0xDC /* Letterbox control 1 */ #define ADV7183_LETTERBOX_CTRL_2 0xDD /* Letterbox control 2 */ #define ADV7183_SD_OFFSET_CB 0xE1 /* SD offset Cb */ diff --git a/drivers/media/pci/saa7164/saa7164-fw.c b/drivers/media/pci/saa7164/saa7164-fw.c index 4ba5eade7ce2..ef4906406ebf 100644 --- a/drivers/media/pci/saa7164/saa7164-fw.c +++ b/drivers/media/pci/saa7164/saa7164-fw.c @@ -422,7 +422,7 @@ int saa7164_downloadfirmware(struct saa7164_dev *dev) return -ENOMEM; } - printk(KERN_INFO "%s() firmware read %Zu bytes.\n", + printk(KERN_INFO "%s() firmware read %zu bytes.\n", __func__, fw->size); if (fw->size != fwlength) { diff --git a/drivers/media/platform/exynos4-is/fimc-core.h b/drivers/media/platform/exynos4-is/fimc-core.h index 5615fefbf7af..c0373aede81a 100644 --- a/drivers/media/platform/exynos4-is/fimc-core.h +++ b/drivers/media/platform/exynos4-is/fimc-core.h @@ -358,7 +358,7 @@ struct fimc_pix_limit { * @pix_limit: pixel size constraints for the scaler * @min_inp_pixsize: minimum input pixel size * @min_out_pixsize: minimum output pixel size - * @hor_offs_align: horizontal pixel offset aligment + * @hor_offs_align: horizontal pixel offset alignment * @min_vsize_align: minimum vertical pixel size alignment */ struct fimc_variant { diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c index 0345b274eccc..91947cf1950e 100644 --- a/drivers/media/tuners/xc5000.c +++ b/drivers/media/tuners/xc5000.c @@ -1144,7 +1144,7 @@ static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force) pr_err("xc5000: Upload failed. rc %d\n", ret); return ret; } - dprintk(1, "firmware read %Zu bytes.\n", fw->size); + dprintk(1, "firmware read %zu bytes.\n", fw->size); if (fw->size != desired_fw->size) { pr_err("xc5000: Firmware file with incorrect size\n"); diff --git a/drivers/media/usb/dvb-usb/dib0700_devices.c b/drivers/media/usb/dvb-usb/dib0700_devices.c index 81d7fd4f7776..85ab3fa48f9a 100644 --- a/drivers/media/usb/dvb-usb/dib0700_devices.c +++ b/drivers/media/usb/dvb-usb/dib0700_devices.c @@ -2414,7 +2414,7 @@ static int stk9090m_frontend_attach(struct dvb_usb_adapter *adap) deb_info("%s: Upload failed. (file not found?)\n", __func__); return -ENODEV; } else { - deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size); + deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); } stk9090m_config.microcode_B_fe_size = state->frontend_firmware->size; stk9090m_config.microcode_B_fe_buffer = state->frontend_firmware->data; @@ -2480,7 +2480,7 @@ static int nim9090md_frontend_attach(struct dvb_usb_adapter *adap) deb_info("%s: Upload failed. (file not found?)\n", __func__); return -EIO; } else { - deb_info("%s: firmware read %Zu bytes.\n", __func__, state->frontend_firmware->size); + deb_info("%s: firmware read %zu bytes.\n", __func__, state->frontend_firmware->size); } nim9090md_config[0].microcode_B_fe_size = state->frontend_firmware->size; nim9090md_config[0].microcode_B_fe_buffer = state->frontend_firmware->data; diff --git a/drivers/media/usb/gspca/t613.c b/drivers/media/usb/gspca/t613.c index 42667710af92..46fb76349000 100644 --- a/drivers/media/usb/gspca/t613.c +++ b/drivers/media/usb/gspca/t613.c @@ -570,9 +570,9 @@ static void setfreq(struct gspca_dev *gspca_dev, s32 val) /* this function is called at probe and resume time */ static int sd_init(struct gspca_dev *gspca_dev) { - /* some of this registers are not really neded, because - * they are overriden by setbrigthness, setcontrast, etc, - * but wont hurt anyway, and can help someone with similar webcam + /* some of this registers are not really needed, because + * they are overridden by setbrigthness, setcontrast, etc., + * but won't hurt anyway, and can help someone with similar webcam * to see the initial parameters.*/ struct sd *sd = (struct sd *) gspca_dev; const struct additional_sensor_data *sensor; diff --git a/drivers/media/usb/tm6000/tm6000-input.c b/drivers/media/usb/tm6000/tm6000-input.c index 4afd4655d562..39c15bb2b20c 100644 --- a/drivers/media/usb/tm6000/tm6000-input.c +++ b/drivers/media/usb/tm6000/tm6000-input.c @@ -438,7 +438,7 @@ int tm6000_ir_init(struct tm6000_core *dev) /* input setup */ rc->allowed_protocols = RC_BIT_RC5 | RC_BIT_NEC; - /* Neded, in order to support NEC remotes with 24 or 32 bits */ + /* Needed, in order to support NEC remotes with 24 or 32 bits */ rc->scancode_mask = 0xffff; rc->priv = ir; rc->change_protocol = tm6000_ir_change_protocol; diff --git a/drivers/media/v4l2-core/tuner-core.c b/drivers/media/v4l2-core/tuner-core.c index 05b5c6652cfa..e48b7c032c95 100644 --- a/drivers/media/v4l2-core/tuner-core.c +++ b/drivers/media/v4l2-core/tuner-core.c @@ -245,7 +245,7 @@ static const struct analog_demod_ops tuner_analog_ops = { * @tuner_callback: an optional function to be called when switching * to analog mode * - * This function applys the tuner config to tuner specified + * This function applies the tuner config to tuner specified * by tun_setup structure. It contains several per-tuner initialization "magic" */ static void set_type(struct i2c_client *c, unsigned int type, @@ -463,7 +463,7 @@ attach_failed: * @sd: subdev descriptor * @tun_setup: type to be associated to a given tuner i2c address * - * This function applys the tuner config to tuner specified + * This function applies the tuner config to tuner specified * by tun_setup structure. * If tuner I2C address is UNSET, then it will only set the device * if the tuner supports the mode specified in the call. diff --git a/drivers/misc/vmw_vmci/vmci_context.c b/drivers/misc/vmw_vmci/vmci_context.c index f866a4baecb5..f35f0c8606b9 100644 --- a/drivers/misc/vmw_vmci/vmci_context.c +++ b/drivers/misc/vmw_vmci/vmci_context.c @@ -303,7 +303,7 @@ int vmci_ctx_enqueue_datagram(u32 cid, struct vmci_datagram *dg) vmci_dg_size = VMCI_DG_SIZE(dg); if (vmci_dg_size > VMCI_MAX_DG_SIZE) { - pr_devel("Datagram too large (bytes=%Zu)\n", vmci_dg_size); + pr_devel("Datagram too large (bytes=%zu)\n", vmci_dg_size); return VMCI_ERROR_INVALID_ARGS; } diff --git a/drivers/misc/vmw_vmci/vmci_queue_pair.c b/drivers/misc/vmw_vmci/vmci_queue_pair.c index f84a4275ca29..498c0854305f 100644 --- a/drivers/misc/vmw_vmci/vmci_queue_pair.c +++ b/drivers/misc/vmw_vmci/vmci_queue_pair.c @@ -2928,7 +2928,7 @@ int vmci_qpair_get_produce_indexes(const struct vmci_qp *qpair, EXPORT_SYMBOL_GPL(vmci_qpair_get_produce_indexes); /* - * vmci_qpair_get_consume_indexes() - Retrieves the indexes of the comsumer. + * vmci_qpair_get_consume_indexes() - Retrieves the indexes of the consumer. * @qpair: Pointer to the queue pair struct. * @consumer_tail: Reference used for storing consumer tail index. * @producer_head: Reference used for storing the producer head index. diff --git a/drivers/mmc/host/mmci_qcom_dml.c b/drivers/mmc/host/mmci_qcom_dml.c index 2b7fc3764803..00750c9d3514 100644 --- a/drivers/mmc/host/mmci_qcom_dml.c +++ b/drivers/mmc/host/mmci_qcom_dml.c @@ -170,7 +170,7 @@ int dml_hw_init(struct mmci_host *host, struct device_node *np) writel_relaxed(producer_id | (consumer_id << CONSUMER_PIPE_ID_SHFT), base + DML_PIPE_ID); - /* Make sure dml intialization is finished */ + /* Make sure dml initialization is finished */ mb(); return 0; diff --git a/drivers/mtd/devices/lart.c b/drivers/mtd/devices/lart.c index 82bd00af5cc3..268aae45b514 100644 --- a/drivers/mtd/devices/lart.c +++ b/drivers/mtd/devices/lart.c @@ -75,18 +75,18 @@ static char module_name[] = "lart"; /* blob */ #define NUM_BLOB_BLOCKS FLASH_NUMBLOCKS_16m_PARAM -#define BLOB_START 0x00000000 -#define BLOB_LEN (NUM_BLOB_BLOCKS * FLASH_BLOCKSIZE_PARAM) +#define PART_BLOB_START 0x00000000 +#define PART_BLOB_LEN (NUM_BLOB_BLOCKS * FLASH_BLOCKSIZE_PARAM) /* kernel */ #define NUM_KERNEL_BLOCKS 7 -#define KERNEL_START (BLOB_START + BLOB_LEN) -#define KERNEL_LEN (NUM_KERNEL_BLOCKS * FLASH_BLOCKSIZE_MAIN) +#define PART_KERNEL_START (PART_BLOB_START + PART_BLOB_LEN) +#define PART_KERNEL_LEN (NUM_KERNEL_BLOCKS * FLASH_BLOCKSIZE_MAIN) /* initial ramdisk */ #define NUM_INITRD_BLOCKS 24 -#define INITRD_START (KERNEL_START + KERNEL_LEN) -#define INITRD_LEN (NUM_INITRD_BLOCKS * FLASH_BLOCKSIZE_MAIN) +#define PART_INITRD_START (PART_KERNEL_START + PART_KERNEL_LEN) +#define PART_INITRD_LEN (NUM_INITRD_BLOCKS * FLASH_BLOCKSIZE_MAIN) /* * See section 4.0 in "3 Volt Fast Boot Block Flash Memory" Intel Datasheet @@ -587,20 +587,20 @@ static struct mtd_partition lart_partitions[] = { /* blob */ { .name = "blob", - .offset = BLOB_START, - .size = BLOB_LEN, + .offset = PART_BLOB_START, + .size = PART_BLOB_LEN, }, /* kernel */ { .name = "kernel", - .offset = KERNEL_START, /* MTDPART_OFS_APPEND */ - .size = KERNEL_LEN, + .offset = PART_KERNEL_START, /* MTDPART_OFS_APPEND */ + .size = PART_KERNEL_LEN, }, /* initial ramdisk / file system */ { .name = "file system", - .offset = INITRD_START, /* MTDPART_OFS_APPEND */ - .size = INITRD_LEN, /* MTDPART_SIZ_FULL */ + .offset = PART_INITRD_START, /* MTDPART_OFS_APPEND */ + .size = PART_INITRD_LEN, /* MTDPART_SIZ_FULL */ } }; #define NUM_PARTITIONS ARRAY_SIZE(lart_partitions) diff --git a/drivers/net/arcnet/arcnet.c b/drivers/net/arcnet/arcnet.c index 6ea963e3b89a..62ee439d5882 100644 --- a/drivers/net/arcnet/arcnet.c +++ b/drivers/net/arcnet/arcnet.c @@ -123,7 +123,7 @@ static int __init arcnet_init(void) arc_proto_map[count] = arc_proto_default; if (BUGLVL(D_DURING)) - pr_info("struct sizes: %Zd %Zd %Zd %Zd %Zd\n", + pr_info("struct sizes: %zd %zd %zd %zd %zd\n", sizeof(struct arc_hardware), sizeof(struct arc_rfc1201), sizeof(struct arc_rfc1051), diff --git a/drivers/net/ethernet/adi/bfin_mac.c b/drivers/net/ethernet/adi/bfin_mac.c index a81731303730..a9ac58c351a0 100644 --- a/drivers/net/ethernet/adi/bfin_mac.c +++ b/drivers/net/ethernet/adi/bfin_mac.c @@ -1206,7 +1206,7 @@ static void bfin_mac_rx(struct bfin_mac_local *lp) /* reserve 2 bytes for RXDWA padding */ skb_reserve(new_skb, NET_IP_ALIGN); /* Invalidate the data cache of skb->data range when it is write back - * cache. It will prevent overwritting the new data from DMA + * cache. It will prevent overwriting the new data from DMA */ blackfin_dcache_invalidate_range((unsigned long)new_skb->head, (unsigned long)new_skb->end); diff --git a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c index d0d0d12b531f..e536301acfde 100644 --- a/drivers/net/ethernet/apm/xgene/xgene_enet_main.c +++ b/drivers/net/ethernet/apm/xgene/xgene_enet_main.c @@ -293,36 +293,29 @@ static int xgene_enet_tx_completion(struct xgene_enet_desc_ring *cp_ring, static int xgene_enet_setup_mss(struct net_device *ndev, u32 mss) { struct xgene_enet_pdata *pdata = netdev_priv(ndev); - bool mss_index_found = false; - int mss_index; + int mss_index = -EBUSY; int i; spin_lock(&pdata->mss_lock); /* Reuse the slot if MSS matches */ - for (i = 0; !mss_index_found && i < NUM_MSS_REG; i++) { + for (i = 0; mss_index < 0 && i < NUM_MSS_REG; i++) { if (pdata->mss[i] == mss) { pdata->mss_refcnt[i]++; mss_index = i; - mss_index_found = true; } } /* Overwrite the slot with ref_count = 0 */ - for (i = 0; !mss_index_found && i < NUM_MSS_REG; i++) { + for (i = 0; mss_index < 0 && i < NUM_MSS_REG; i++) { if (!pdata->mss_refcnt[i]) { pdata->mss_refcnt[i]++; pdata->mac_ops->set_mss(pdata, mss, i); pdata->mss[i] = mss; mss_index = i; - mss_index_found = true; } } - /* No slots with ref_count = 0 available, return busy */ - if (!mss_index_found) - mss_index = -EBUSY; - spin_unlock(&pdata->mss_lock); return mss_index; diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c index 0ee6e208aa07..50d88d3e03b6 100644 --- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c +++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c @@ -817,7 +817,7 @@ static void bcm_enet_adjust_phy_link(struct net_device *dev) rx_pause_en = 1; tx_pause_en = 1; } else if (!priv->pause_auto) { - /* pause setting overrided by user */ + /* pause setting overridden by user */ rx_pause_en = priv->pause_rx; tx_pause_en = priv->pause_tx; } else { diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c index 05356efdbf93..b209b7f6093e 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_link.c @@ -6957,7 +6957,7 @@ int bnx2x_link_update(struct link_params *params, struct link_vars *vars) * hence its link is expected to be down * - SECOND_PHY means that first phy should not be able * to link up by itself (using configuration) - * - DEFAULT should be overriden during initialiazation + * - DEFAULT should be overridden during initialization */ DP(NETIF_MSG_LINK, "Invalid link indication" "mpc=0x%x. DISABLING LINK !!!\n", diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c index 016d481c6476..30606b11b128 100644 --- a/drivers/net/ethernet/cadence/macb.c +++ b/drivers/net/ethernet/cadence/macb.c @@ -1622,7 +1622,7 @@ static void macb_init_rx_buffer_size(struct macb *bp, size_t size) } } - netdev_dbg(bp->dev, "mtu [%u] rx_buffer_size [%Zu]\n", + netdev_dbg(bp->dev, "mtu [%u] rx_buffer_size [%zu]\n", bp->dev->mtu, bp->rx_buffer_size); } diff --git a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c index acc231293e4d..f6e739da7bb7 100644 --- a/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c +++ b/drivers/net/ethernet/chelsio/cxgb4/cxgb4_debugfs.c @@ -1416,7 +1416,7 @@ static unsigned int xdigit2int(unsigned char c) * <pattern data>[/<pattern mask>][@<anchor>] * * Up to 2 filter patterns can be specified. If 2 are supplied the first one - * must be anchored at 0. An omited mask is taken as a mask of 1s, an omitted + * must be anchored at 0. An omitted mask is taken as a mask of 1s, an omitted * anchor is taken as 0. */ static ssize_t mps_trc_write(struct file *file, const char __user *buf, diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c index cbbf8648307a..78460c52b7c4 100644 --- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c +++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c @@ -847,9 +847,7 @@ static void i40e_free_vf_res(struct i40e_vf *vf) wr32(hw, reg_idx, reg); i40e_flush(hw); } - /* reset some of the state varibles keeping - * track of the resources - */ + /* reset some of the state variables keeping track of the resources */ vf->num_queue_pairs = 0; vf->vf_states = 0; clear_bit(I40E_VF_STAT_INIT, &vf->vf_states); diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c index 2788a5409023..68812d783f33 100644 --- a/drivers/net/ethernet/intel/igb/e1000_phy.c +++ b/drivers/net/ethernet/intel/igb/e1000_phy.c @@ -294,7 +294,7 @@ s32 igb_write_phy_reg_i2c(struct e1000_hw *hw, u32 offset, u16 data) u32 i, i2ccmd = 0; u16 phy_data_swapped; - /* Prevent overwritting SFP I2C EEPROM which is at A0 address.*/ + /* Prevent overwriting SFP I2C EEPROM which is at A0 address.*/ if ((hw->phy.addr == 0) || (hw->phy.addr > 7)) { hw_dbg("PHY I2C Address %d is out of range.\n", hw->phy.addr); diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c index 30535e6b68f0..c8ac46049f34 100644 --- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c +++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82599.c @@ -1449,7 +1449,7 @@ do { \ * @atr_input: input bitstream to compute the hash on * @input_mask: mask for the input bitstream * - * This function serves two main purposes. First it applys the input_mask + * This function serves two main purposes. First it applies the input_mask * to the atr_input resulting in a cleaned up atr_input data stream. * Secondly it computes the hash and stores it in the bkt_hash field at * the end of the input byte stream. This way it will be available for diff --git a/drivers/net/ethernet/mellanox/mlx4/en_clock.c b/drivers/net/ethernet/mellanox/mlx4/en_clock.c index e7b81a305469..024788549c25 100644 --- a/drivers/net/ethernet/mellanox/mlx4/en_clock.c +++ b/drivers/net/ethernet/mellanox/mlx4/en_clock.c @@ -89,10 +89,17 @@ void mlx4_en_remove_timestamp(struct mlx4_en_dev *mdev) } } +#define MLX4_EN_WRAP_AROUND_SEC 10UL +/* By scheduling the overflow check every 5 seconds, we have a reasonably + * good chance we wont miss a wrap around. + * TOTO: Use a timer instead of a work queue to increase the guarantee. + */ +#define MLX4_EN_OVERFLOW_PERIOD (MLX4_EN_WRAP_AROUND_SEC * HZ / 2) + void mlx4_en_ptp_overflow_check(struct mlx4_en_dev *mdev) { bool timeout = time_is_before_jiffies(mdev->last_overflow_check + - mdev->overflow_period); + MLX4_EN_OVERFLOW_PERIOD); unsigned long flags; if (timeout) { @@ -237,7 +244,6 @@ static const struct ptp_clock_info mlx4_en_ptp_clock_info = { .enable = mlx4_en_phc_enable, }; -#define MLX4_EN_WRAP_AROUND_SEC 10ULL /* This function calculates the max shift that enables the user range * of MLX4_EN_WRAP_AROUND_SEC values in the cycles register. @@ -258,7 +264,6 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) { struct mlx4_dev *dev = mdev->dev; unsigned long flags; - u64 ns, zero = 0; /* mlx4_en_init_timestamp is called for each netdev. * mdev->ptp_clock is common for all ports, skip initialization if @@ -282,13 +287,6 @@ void mlx4_en_init_timestamp(struct mlx4_en_dev *mdev) ktime_to_ns(ktime_get_real())); write_sequnlock_irqrestore(&mdev->clock_lock, flags); - /* Calculate period in seconds to call the overflow watchdog - to make - * sure counter is checked at least once every wrap around. - */ - ns = cyclecounter_cyc2ns(&mdev->cycles, mdev->cycles.mask, zero, &zero); - do_div(ns, NSEC_PER_SEC / 2 / HZ); - mdev->overflow_period = ns; - /* Configure the PHC */ mdev->ptp_clock_info = mlx4_en_ptp_clock_info; snprintf(mdev->ptp_clock_info.name, 16, "mlx4 ptp"); diff --git a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h index 4941b692e947..3629ce11a68b 100644 --- a/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h +++ b/drivers/net/ethernet/mellanox/mlx4/mlx4_en.h @@ -430,7 +430,6 @@ struct mlx4_en_dev { seqlock_t clock_lock; struct timecounter clock; unsigned long last_overflow_check; - unsigned long overflow_period; struct ptp_clock *ptp_clock; struct ptp_clock_info ptp_clock_info; struct notifier_block nb; diff --git a/drivers/net/ethernet/micrel/ksz884x.c b/drivers/net/ethernet/micrel/ksz884x.c index ee38c18c2d2d..ee1c78abab0b 100644 --- a/drivers/net/ethernet/micrel/ksz884x.c +++ b/drivers/net/ethernet/micrel/ksz884x.c @@ -1251,10 +1251,10 @@ struct ksz_port_info { * @tx_size: Transmit data size. Used for TX optimization. * The maximum is defined by MAX_TX_HELD_SIZE. * @perm_addr: Permanent MAC address. - * @override_addr: Overrided MAC address. + * @override_addr: Overridden MAC address. * @address: Additional MAC address entries. * @addr_list_size: Additional MAC address list size. - * @mac_override: Indication of MAC address overrided. + * @mac_override: Indication of MAC address overridden. * @promiscuous: Counter to keep track of promiscuous mode set. * @all_multi: Counter to keep track of all multicast mode set. * @multi_list: Multicast address entries. @@ -4042,7 +4042,7 @@ static int empty_addr(u8 *addr) * @hw: The hardware instance. * * This routine programs the MAC address of the hardware when the address is - * overrided. + * overridden. */ static void hw_set_addr(struct ksz_hw *hw) { @@ -7043,7 +7043,7 @@ static int pcidev_init(struct pci_dev *pdev, const struct pci_device_id *id) if (macaddr[0] != ':') get_mac_addr(hw_priv, macaddr, MAIN_PORT); - /* Read MAC address and initialize override address if not overrided. */ + /* Read MAC address and initialize override address if not overridden. */ hw_read_addr(hw); /* Multiple device interfaces mode requires a second MAC address. */ diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c index c5c1d0e0c16f..118723ea681a 100644 --- a/drivers/net/ethernet/neterion/s2io.c +++ b/drivers/net/ethernet/neterion/s2io.c @@ -5397,7 +5397,7 @@ static void s2io_ethtool_gdrvinfo(struct net_device *dev, * s2io_nic structure. * @regs : pointer to the structure with parameters given by ethtool for * dumping the registers. - * @reg_space: The input argumnet into which all the registers are dumped. + * @reg_space: The input argument into which all the registers are dumped. * Description: * Dumps the entire register space of xFrame NIC into the user given * buffer area. diff --git a/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c b/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c index db55e6d89cf4..0452848d1316 100644 --- a/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c +++ b/drivers/net/ethernet/neterion/vxge/vxge-ethtool.c @@ -119,7 +119,7 @@ static void vxge_ethtool_gdrvinfo(struct net_device *dev, * @dev: device pointer. * @regs: pointer to the structure with parameters given by ethtool for * dumping the registers. - * @reg_space: The input argumnet into which all the registers are dumped. + * @reg_space: The input argument into which all the registers are dumped. * * Dumps the vpath register space of Titan NIC into the user given * buffer area. diff --git a/drivers/net/ethernet/qlogic/qed/qed.h b/drivers/net/ethernet/qlogic/qed/qed.h index 61a9cd5be497..00c17fa6545b 100644 --- a/drivers/net/ethernet/qlogic/qed/qed.h +++ b/drivers/net/ethernet/qlogic/qed/qed.h @@ -688,7 +688,9 @@ static inline u8 qed_concrete_to_sw_fid(struct qed_dev *cdev, #define OOO_LB_TC 9 int qed_configure_vport_wfq(struct qed_dev *cdev, u16 vp_id, u32 rate); -void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev, u32 min_pf_rate); +void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev, + struct qed_ptt *p_ptt, + u32 min_pf_rate); void qed_clean_wfq_db(struct qed_hwfn *p_hwfn, struct qed_ptt *p_ptt); #define QED_LEADING_HWFN(dev) (&dev->hwfns[0]) diff --git a/drivers/net/ethernet/qlogic/qed/qed_dev.c b/drivers/net/ethernet/qlogic/qed/qed_dev.c index d6c5a8165b5f..e2a081ceaf52 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_dev.c +++ b/drivers/net/ethernet/qlogic/qed/qed_dev.c @@ -3198,7 +3198,8 @@ int qed_configure_vport_wfq(struct qed_dev *cdev, u16 vp_id, u32 rate) } /* API to configure WFQ from mcp link change */ -void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev, u32 min_pf_rate) +void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev, + struct qed_ptt *p_ptt, u32 min_pf_rate) { int i; @@ -3212,8 +3213,7 @@ void qed_configure_vp_wfq_on_link_change(struct qed_dev *cdev, u32 min_pf_rate) for_each_hwfn(cdev, i) { struct qed_hwfn *p_hwfn = &cdev->hwfns[i]; - __qed_configure_vp_wfq_on_link_change(p_hwfn, - p_hwfn->p_dpc_ptt, + __qed_configure_vp_wfq_on_link_change(p_hwfn, p_ptt, min_pf_rate); } } diff --git a/drivers/net/ethernet/qlogic/qed/qed_mcp.c b/drivers/net/ethernet/qlogic/qed/qed_mcp.c index 314022df3469..87fde205149f 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_mcp.c +++ b/drivers/net/ethernet/qlogic/qed/qed_mcp.c @@ -679,7 +679,8 @@ static void qed_mcp_handle_link_change(struct qed_hwfn *p_hwfn, /* Min bandwidth configuration */ __qed_configure_pf_min_bandwidth(p_hwfn, p_ptt, p_link, min_bw); - qed_configure_vp_wfq_on_link_change(p_hwfn->cdev, p_link->min_pf_rate); + qed_configure_vp_wfq_on_link_change(p_hwfn->cdev, p_ptt, + p_link->min_pf_rate); p_link->an = !!(status & LINK_STATUS_AUTO_NEGOTIATE_ENABLED); p_link->an_complete = !!(status & diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.c b/drivers/net/ethernet/qlogic/qed/qed_sriov.c index 29ed785f1dc2..253c2bbe1e4e 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.c +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.c @@ -3014,8 +3014,7 @@ cleanup: ack_vfs[vfid / 32] |= BIT((vfid % 32)); p_hwfn->pf_iov_info->pending_flr[rel_vf_id / 64] &= ~(1ULL << (rel_vf_id % 64)); - p_hwfn->pf_iov_info->pending_events[rel_vf_id / 64] &= - ~(1ULL << (rel_vf_id % 64)); + p_vf->vf_mbx.b_pending_msg = false; } return rc; @@ -3128,11 +3127,20 @@ static void qed_iov_process_mbx_req(struct qed_hwfn *p_hwfn, mbx = &p_vf->vf_mbx; /* qed_iov_process_mbx_request */ - DP_VERBOSE(p_hwfn, QED_MSG_IOV, - "VF[%02x]: Processing mailbox message\n", p_vf->abs_vf_id); + if (!mbx->b_pending_msg) { + DP_NOTICE(p_hwfn, + "VF[%02x]: Trying to process mailbox message when none is pending\n", + p_vf->abs_vf_id); + return; + } + mbx->b_pending_msg = false; mbx->first_tlv = mbx->req_virt->first_tlv; + DP_VERBOSE(p_hwfn, QED_MSG_IOV, + "VF[%02x]: Processing mailbox message [type %04x]\n", + p_vf->abs_vf_id, mbx->first_tlv.tl.type); + /* check if tlv type is known */ if (qed_iov_tlv_supported(mbx->first_tlv.tl.type) && !p_vf->b_malicious) { @@ -3219,20 +3227,19 @@ static void qed_iov_process_mbx_req(struct qed_hwfn *p_hwfn, } } -static void qed_iov_pf_add_pending_events(struct qed_hwfn *p_hwfn, u8 vfid) +void qed_iov_pf_get_pending_events(struct qed_hwfn *p_hwfn, u64 *events) { - u64 add_bit = 1ULL << (vfid % 64); + int i; - p_hwfn->pf_iov_info->pending_events[vfid / 64] |= add_bit; -} + memset(events, 0, sizeof(u64) * QED_VF_ARRAY_LENGTH); -static void qed_iov_pf_get_and_clear_pending_events(struct qed_hwfn *p_hwfn, - u64 *events) -{ - u64 *p_pending_events = p_hwfn->pf_iov_info->pending_events; + qed_for_each_vf(p_hwfn, i) { + struct qed_vf_info *p_vf; - memcpy(events, p_pending_events, sizeof(u64) * QED_VF_ARRAY_LENGTH); - memset(p_pending_events, 0, sizeof(u64) * QED_VF_ARRAY_LENGTH); + p_vf = &p_hwfn->pf_iov_info->vfs_array[i]; + if (p_vf->vf_mbx.b_pending_msg) + events[i / 64] |= 1ULL << (i % 64); + } } static struct qed_vf_info *qed_sriov_get_vf_from_absid(struct qed_hwfn *p_hwfn, @@ -3266,7 +3273,7 @@ static int qed_sriov_vfpf_msg(struct qed_hwfn *p_hwfn, p_vf->vf_mbx.pending_req = (((u64)vf_msg->hi) << 32) | vf_msg->lo; /* Mark the event and schedule the workqueue */ - qed_iov_pf_add_pending_events(p_hwfn, p_vf->relative_vf_id); + p_vf->vf_mbx.b_pending_msg = true; qed_schedule_iov(p_hwfn, QED_IOV_WQ_MSG_FLAG); return 0; @@ -4030,7 +4037,7 @@ static void qed_handle_vf_msg(struct qed_hwfn *hwfn) return; } - qed_iov_pf_get_and_clear_pending_events(hwfn, events); + qed_iov_pf_get_pending_events(hwfn, events); DP_VERBOSE(hwfn, QED_MSG_IOV, "Event mask of VF events: 0x%llx 0x%llx 0x%llx\n", diff --git a/drivers/net/ethernet/qlogic/qed/qed_sriov.h b/drivers/net/ethernet/qlogic/qed/qed_sriov.h index fc08cc2da6a7..a89605821522 100644 --- a/drivers/net/ethernet/qlogic/qed/qed_sriov.h +++ b/drivers/net/ethernet/qlogic/qed/qed_sriov.h @@ -140,6 +140,9 @@ struct qed_iov_vf_mbx { /* Address in VF where a pending message is located */ dma_addr_t pending_req; + /* Message from VF awaits handling */ + bool b_pending_msg; + u8 *offset; /* saved VF request header */ @@ -232,7 +235,6 @@ struct qed_vf_info { */ struct qed_pf_iov { struct qed_vf_info vfs_array[MAX_NUM_VFS]; - u64 pending_events[QED_VF_ARRAY_LENGTH]; u64 pending_flr[QED_VF_ARRAY_LENGTH]; /* Allocate message address continuosuly and split to each VF */ diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c index 99b187bfdd55..718bf58a7da6 100644 --- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c +++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c @@ -178,7 +178,7 @@ const u32 qlcnic_83xx_reg_tbl[] = { 0x3540, /* Device state, DRV_REG1 */ 0x3544, /* Driver state, DRV_REG2 */ 0x3548, /* Driver scratch, DRV_REG3 */ - 0x354C, /* Device partiton info, DRV_REG4 */ + 0x354C, /* Device partition info, DRV_REG4 */ 0x3524, /* Driver IDC ver, DRV_REG5 */ 0x3550, /* FW_VER_MAJOR */ 0x3554, /* FW_VER_MINOR */ diff --git a/drivers/net/ethernet/sfc/mcdi_pcol.h b/drivers/net/ethernet/sfc/mcdi_pcol.h index 47ced8a898ca..91fb54fd03d9 100644 --- a/drivers/net/ethernet/sfc/mcdi_pcol.h +++ b/drivers/net/ethernet/sfc/mcdi_pcol.h @@ -10832,7 +10832,7 @@ /***********************************/ /* MC_CMD_GET_LICENSED_V3_FEATURE_STATES - * Query the state of an one or more licensed features. (Note that the actual + * Query the state of one or more licensed features. (Note that the actual * state may be invalidated by the MC_CMD_LICENSING_V3 OP_UPDATE_LICENSE * operation or a reboot of the MC.) Used for V3 licensing (Medford) */ diff --git a/drivers/net/ethernet/sis/sis900.c b/drivers/net/ethernet/sis/sis900.c index 19a458716f1a..1b6f6171d078 100644 --- a/drivers/net/ethernet/sis/sis900.c +++ b/drivers/net/ethernet/sis/sis900.c @@ -176,7 +176,7 @@ struct sis900_private { u32 msg_enable; - unsigned int cur_rx, dirty_rx; /* producer/comsumer pointers for Tx/Rx ring */ + unsigned int cur_rx, dirty_rx; /* producer/consumer pointers for Tx/Rx ring */ unsigned int cur_tx, dirty_tx; /* The saved address of a sent/receive-in-place packet buffer */ diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h index 144fe84e8a53..04d9245b7149 100644 --- a/drivers/net/ethernet/stmicro/stmmac/common.h +++ b/drivers/net/ethernet/stmicro/stmmac/common.h @@ -416,7 +416,7 @@ struct stmmac_dma_ops { /* Configure the AXI Bus Mode Register */ void (*axi)(void __iomem *ioaddr, struct stmmac_axi *axi); /* Dump DMA registers */ - void (*dump_regs) (void __iomem *ioaddr); + void (*dump_regs)(void __iomem *ioaddr, u32 *reg_space); /* Set tx/rx threshold in the csr6 register * An invalid value enables the store-and-forward mode */ void (*dma_mode)(void __iomem *ioaddr, int txmode, int rxmode, @@ -456,7 +456,7 @@ struct stmmac_ops { /* Enable RX Queues */ void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue); /* Dump MAC registers */ - void (*dump_regs)(struct mac_device_info *hw); + void (*dump_regs)(struct mac_device_info *hw, u32 *reg_space); /* Handle extra events on specific interrupts hw dependent */ int (*host_irq_status)(struct mac_device_info *hw, struct stmmac_extra_stats *x); diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c index 91c8926b7479..19b9b3087099 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_core.c @@ -92,17 +92,13 @@ static int dwmac1000_rx_ipc_enable(struct mac_device_info *hw) return !!(value & GMAC_CONTROL_IPC); } -static void dwmac1000_dump_regs(struct mac_device_info *hw) +static void dwmac1000_dump_regs(struct mac_device_info *hw, u32 *reg_space) { void __iomem *ioaddr = hw->pcsr; int i; - pr_info("\tDWMAC1000 regs (base addr = 0x%p)\n", ioaddr); - for (i = 0; i < 55; i++) { - int offset = i * 4; - pr_info("\tReg No. %d (offset 0x%x): 0x%08x\n", i, - offset, readl(ioaddr + offset)); - } + for (i = 0; i < 55; i++) + reg_space[i] = readl(ioaddr + i * 4); } static void dwmac1000_set_umac_addr(struct mac_device_info *hw, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c index fbaec0ffd9ef..d3654a447046 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac1000_dma.c @@ -201,18 +201,14 @@ static void dwmac1000_dma_operation_mode(void __iomem *ioaddr, int txmode, writel(csr6, ioaddr + DMA_CONTROL); } -static void dwmac1000_dump_dma_regs(void __iomem *ioaddr) +static void dwmac1000_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space) { int i; - pr_info(" DMA registers\n"); - for (i = 0; i < 22; i++) { - if ((i < 9) || (i > 17)) { - int offset = i * 4; - pr_err("\t Reg No. %d (offset 0x%x): 0x%08x\n", i, - (DMA_BUS_MODE + offset), - readl(ioaddr + DMA_BUS_MODE + offset)); - } - } + + for (i = 0; i < 22; i++) + if ((i < 9) || (i > 17)) + reg_space[DMA_BUS_MODE / 4 + i] = + readl(ioaddr + DMA_BUS_MODE + i * 4); } static void dwmac1000_get_hw_feature(void __iomem *ioaddr, diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c index 8ab518997b1b..e370ccec6176 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_core.c @@ -40,28 +40,18 @@ static void dwmac100_core_init(struct mac_device_info *hw, int mtu) #endif } -static void dwmac100_dump_mac_regs(struct mac_device_info *hw) +static void dwmac100_dump_mac_regs(struct mac_device_info *hw, u32 *reg_space) { void __iomem *ioaddr = hw->pcsr; - pr_info("\t----------------------------------------------\n" - "\t DWMAC 100 CSR (base addr = 0x%p)\n" - "\t----------------------------------------------\n", ioaddr); - pr_info("\tcontrol reg (offset 0x%x): 0x%08x\n", MAC_CONTROL, - readl(ioaddr + MAC_CONTROL)); - pr_info("\taddr HI (offset 0x%x): 0x%08x\n ", MAC_ADDR_HIGH, - readl(ioaddr + MAC_ADDR_HIGH)); - pr_info("\taddr LO (offset 0x%x): 0x%08x\n", MAC_ADDR_LOW, - readl(ioaddr + MAC_ADDR_LOW)); - pr_info("\tmulticast hash HI (offset 0x%x): 0x%08x\n", - MAC_HASH_HIGH, readl(ioaddr + MAC_HASH_HIGH)); - pr_info("\tmulticast hash LO (offset 0x%x): 0x%08x\n", - MAC_HASH_LOW, readl(ioaddr + MAC_HASH_LOW)); - pr_info("\tflow control (offset 0x%x): 0x%08x\n", - MAC_FLOW_CTRL, readl(ioaddr + MAC_FLOW_CTRL)); - pr_info("\tVLAN1 tag (offset 0x%x): 0x%08x\n", MAC_VLAN1, - readl(ioaddr + MAC_VLAN1)); - pr_info("\tVLAN2 tag (offset 0x%x): 0x%08x\n", MAC_VLAN2, - readl(ioaddr + MAC_VLAN2)); + + reg_space[MAC_CONTROL / 4] = readl(ioaddr + MAC_CONTROL); + reg_space[MAC_ADDR_HIGH / 4] = readl(ioaddr + MAC_ADDR_HIGH); + reg_space[MAC_ADDR_LOW / 4] = readl(ioaddr + MAC_ADDR_LOW); + reg_space[MAC_HASH_HIGH / 4] = readl(ioaddr + MAC_HASH_HIGH); + reg_space[MAC_HASH_LOW / 4] = readl(ioaddr + MAC_HASH_LOW); + reg_space[MAC_FLOW_CTRL / 4] = readl(ioaddr + MAC_FLOW_CTRL); + reg_space[MAC_VLAN1 / 4] = readl(ioaddr + MAC_VLAN1); + reg_space[MAC_VLAN2 / 4] = readl(ioaddr + MAC_VLAN2); } static int dwmac100_rx_ipc_enable(struct mac_device_info *hw) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c index d40e91e8fc7b..eef2f222ce9a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac100_dma.c @@ -66,19 +66,18 @@ static void dwmac100_dma_operation_mode(void __iomem *ioaddr, int txmode, writel(csr6, ioaddr + DMA_CONTROL); } -static void dwmac100_dump_dma_regs(void __iomem *ioaddr) +static void dwmac100_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space) { int i; - pr_debug("DWMAC 100 DMA CSR\n"); for (i = 0; i < 9; i++) - pr_debug("\t CSR%d (offset 0x%x): 0x%08x\n", i, - (DMA_BUS_MODE + i * 4), - readl(ioaddr + DMA_BUS_MODE + i * 4)); + reg_space[DMA_BUS_MODE / 4 + i] = + readl(ioaddr + DMA_BUS_MODE + i * 4); - pr_debug("\tCSR20 (0x%x): 0x%08x, CSR21 (0x%x): 0x%08x\n", - DMA_CUR_TX_BUF_ADDR, readl(ioaddr + DMA_CUR_TX_BUF_ADDR), - DMA_CUR_RX_BUF_ADDR, readl(ioaddr + DMA_CUR_RX_BUF_ADDR)); + reg_space[DMA_CUR_TX_BUF_ADDR / 4] = + readl(ioaddr + DMA_CUR_TX_BUF_ADDR); + reg_space[DMA_CUR_RX_BUF_ADDR / 4] = + readl(ioaddr + DMA_CUR_RX_BUF_ADDR); } /* DMA controller has two counters to track the number of the missed frames. */ diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c index 202216cd6789..1e79e6529c4a 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c @@ -70,19 +70,13 @@ static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue) writel(value, ioaddr + GMAC_RXQ_CTRL0); } -static void dwmac4_dump_regs(struct mac_device_info *hw) +static void dwmac4_dump_regs(struct mac_device_info *hw, u32 *reg_space) { void __iomem *ioaddr = hw->pcsr; int i; - pr_debug("\tDWMAC4 regs (base addr = 0x%p)\n", ioaddr); - - for (i = 0; i < GMAC_REG_NUM; i++) { - int offset = i * 4; - - pr_debug("\tReg No. %d (offset 0x%x): 0x%08x\n", i, - offset, readl(ioaddr + offset)); - } + for (i = 0; i < GMAC_REG_NUM; i++) + reg_space[i] = readl(ioaddr + i * 4); } static int dwmac4_rx_ipc_enable(struct mac_device_info *hw) diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c index 377d1b44d4f2..f97b0d5d9987 100644 --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_dma.c @@ -127,53 +127,51 @@ static void dwmac4_dma_init(void __iomem *ioaddr, dwmac4_dma_init_channel(ioaddr, dma_cfg, dma_tx, dma_rx, i); } -static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel) +static void _dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 channel, + u32 *reg_space) { - pr_debug(" Channel %d\n", channel); - pr_debug("\tDMA_CHAN_CONTROL, offset: 0x%x, val: 0x%x\n", 0, - readl(ioaddr + DMA_CHAN_CONTROL(channel))); - pr_debug("\tDMA_CHAN_TX_CONTROL, offset: 0x%x, val: 0x%x\n", 0x4, - readl(ioaddr + DMA_CHAN_TX_CONTROL(channel))); - pr_debug("\tDMA_CHAN_RX_CONTROL, offset: 0x%x, val: 0x%x\n", 0x8, - readl(ioaddr + DMA_CHAN_RX_CONTROL(channel))); - pr_debug("\tDMA_CHAN_TX_BASE_ADDR, offset: 0x%x, val: 0x%x\n", 0x14, - readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(channel))); - pr_debug("\tDMA_CHAN_RX_BASE_ADDR, offset: 0x%x, val: 0x%x\n", 0x1c, - readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(channel))); - pr_debug("\tDMA_CHAN_TX_END_ADDR, offset: 0x%x, val: 0x%x\n", 0x20, - readl(ioaddr + DMA_CHAN_TX_END_ADDR(channel))); - pr_debug("\tDMA_CHAN_RX_END_ADDR, offset: 0x%x, val: 0x%x\n", 0x28, - readl(ioaddr + DMA_CHAN_RX_END_ADDR(channel))); - pr_debug("\tDMA_CHAN_TX_RING_LEN, offset: 0x%x, val: 0x%x\n", 0x2c, - readl(ioaddr + DMA_CHAN_TX_RING_LEN(channel))); - pr_debug("\tDMA_CHAN_RX_RING_LEN, offset: 0x%x, val: 0x%x\n", 0x30, - readl(ioaddr + DMA_CHAN_RX_RING_LEN(channel))); - pr_debug("\tDMA_CHAN_INTR_ENA, offset: 0x%x, val: 0x%x\n", 0x34, - readl(ioaddr + DMA_CHAN_INTR_ENA(channel))); - pr_debug("\tDMA_CHAN_RX_WATCHDOG, offset: 0x%x, val: 0x%x\n", 0x38, - readl(ioaddr + DMA_CHAN_RX_WATCHDOG(channel))); - pr_debug("\tDMA_CHAN_SLOT_CTRL_STATUS, offset: 0x%x, val: 0x%x\n", 0x3c, - readl(ioaddr + DMA_CHAN_SLOT_CTRL_STATUS(channel))); - pr_debug("\tDMA_CHAN_CUR_TX_DESC, offset: 0x%x, val: 0x%x\n", 0x44, - readl(ioaddr + DMA_CHAN_CUR_TX_DESC(channel))); - pr_debug("\tDMA_CHAN_CUR_RX_DESC, offset: 0x%x, val: 0x%x\n", 0x4c, - readl(ioaddr + DMA_CHAN_CUR_RX_DESC(channel))); - pr_debug("\tDMA_CHAN_CUR_TX_BUF_ADDR, offset: 0x%x, val: 0x%x\n", 0x54, - readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(channel))); - pr_debug("\tDMA_CHAN_CUR_RX_BUF_ADDR, offset: 0x%x, val: 0x%x\n", 0x5c, - readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(channel))); - pr_debug("\tDMA_CHAN_STATUS, offset: 0x%x, val: 0x%x\n", 0x60, - readl(ioaddr + DMA_CHAN_STATUS(channel))); + reg_space[DMA_CHAN_CONTROL(channel) / 4] = + readl(ioaddr + DMA_CHAN_CONTROL(channel)); + reg_space[DMA_CHAN_TX_CONTROL(channel) / 4] = + readl(ioaddr + DMA_CHAN_TX_CONTROL(channel)); + reg_space[DMA_CHAN_RX_CONTROL(channel) / 4] = + readl(ioaddr + DMA_CHAN_RX_CONTROL(channel)); + reg_space[DMA_CHAN_TX_BASE_ADDR(channel) / 4] = + readl(ioaddr + DMA_CHAN_TX_BASE_ADDR(channel)); + reg_space[DMA_CHAN_RX_BASE_ADDR(channel) / 4] = + readl(ioaddr + DMA_CHAN_RX_BASE_ADDR(channel)); + reg_space[DMA_CHAN_TX_END_ADDR(channel) / 4] = + readl(ioaddr + DMA_CHAN_TX_END_ADDR(channel)); + reg_space[DMA_CHAN_RX_END_ADDR(channel) / 4] = + readl(ioaddr + DMA_CHAN_RX_END_ADDR(channel)); + reg_space[DMA_CHAN_TX_RING_LEN(channel) / 4] = + readl(ioaddr + DMA_CHAN_TX_RING_LEN(channel)); + reg_space[DMA_CHAN_RX_RING_LEN(channel) / 4] = + readl(ioaddr + DMA_CHAN_RX_RING_LEN(channel)); + reg_space[DMA_CHAN_INTR_ENA(channel) / 4] = + readl(ioaddr + DMA_CHAN_INTR_ENA(channel)); + reg_space[DMA_CHAN_RX_WATCHDOG(channel) / 4] = + readl(ioaddr + DMA_CHAN_RX_WATCHDOG(channel)); + reg_space[DMA_CHAN_SLOT_CTRL_STATUS(channel) / 4] = + readl(ioaddr + DMA_CHAN_SLOT_CTRL_STATUS(channel)); + reg_space[DMA_CHAN_CUR_TX_DESC(channel) / 4] = + readl(ioaddr + DMA_CHAN_CUR_TX_DESC(channel)); + reg_space[DMA_CHAN_CUR_RX_DESC(channel) / 4] = + readl(ioaddr + DMA_CHAN_CUR_RX_DESC(channel)); + reg_space[DMA_CHAN_CUR_TX_BUF_ADDR(channel) / 4] = + readl(ioaddr + DMA_CHAN_CUR_TX_BUF_ADDR(channel)); + reg_space[DMA_CHAN_CUR_RX_BUF_ADDR(channel) / 4] = + readl(ioaddr + DMA_CHAN_CUR_RX_BUF_ADDR(channel)); + reg_space[DMA_CHAN_STATUS(channel) / 4] = + readl(ioaddr + DMA_CHAN_STATUS(channel)); } -static void dwmac4_dump_dma_regs(void __iomem *ioaddr) +static void dwmac4_dump_dma_regs(void __iomem *ioaddr, u32 *reg_space) { int i; - pr_debug(" GMAC4 DMA registers\n"); - for (i = 0; i < DMA_CHANNEL_NB_MAX; i++) - _dwmac4_dump_dma_regs(ioaddr, i); + _dwmac4_dump_dma_regs(ioaddr, i, reg_space); } static void dwmac4_rx_watchdog(void __iomem *ioaddr, u32 riwt) diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c index 5ff6bc4eb8f1..85d64114e159 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ethtool.c @@ -435,32 +435,14 @@ static int stmmac_ethtool_get_regs_len(struct net_device *dev) static void stmmac_ethtool_gregs(struct net_device *dev, struct ethtool_regs *regs, void *space) { - int i; u32 *reg_space = (u32 *) space; struct stmmac_priv *priv = netdev_priv(dev); memset(reg_space, 0x0, REG_SPACE_SIZE); - if (priv->plat->has_gmac || priv->plat->has_gmac4) { - /* MAC registers */ - for (i = 0; i < 55; i++) - reg_space[i] = readl(priv->ioaddr + (i * 4)); - /* DMA registers */ - for (i = 0; i < 22; i++) - reg_space[i + 55] = - readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4))); - } else { - /* MAC registers */ - for (i = 0; i < 12; i++) - reg_space[i] = readl(priv->ioaddr + (i * 4)); - /* DMA registers */ - for (i = 0; i < 9; i++) - reg_space[i + 12] = - readl(priv->ioaddr + (DMA_BUS_MODE + (i * 4))); - reg_space[22] = readl(priv->ioaddr + DMA_CUR_TX_BUF_ADDR); - reg_space[23] = readl(priv->ioaddr + DMA_CUR_RX_BUF_ADDR); - } + priv->hw->mac->dump_regs(priv->hw, reg_space); + priv->hw->dma->dump_regs(priv->ioaddr, reg_space); } static void diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c index 3cbe09682afe..4498a3861aa3 100644 --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c @@ -1729,11 +1729,6 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp) priv->hw->dma->start_tx(priv->ioaddr); priv->hw->dma->start_rx(priv->ioaddr); - /* Dump DMA/MAC registers */ - if (netif_msg_hw(priv)) { - priv->hw->mac->dump_regs(priv->hw); - priv->hw->dma->dump_regs(priv->ioaddr); - } priv->tx_lpi_timer = STMMAC_DEFAULT_TWT_LS; if ((priv->use_riwt) && (priv->hw->dma->rx_watchdog)) { diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c index bda0c6413450..89698741682f 100644 --- a/drivers/net/gtp.c +++ b/drivers/net/gtp.c @@ -1330,7 +1330,7 @@ static int __init gtp_init(void) if (err < 0) goto unreg_genl_family; - pr_info("GTP module loaded (pdp ctx size %Zd bytes)\n", + pr_info("GTP module loaded (pdp ctx size %zd bytes)\n", sizeof(struct pdp_ctx)); return 0; diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c index d6f7838455dd..1be69d8bc909 100644 --- a/drivers/net/phy/phy.c +++ b/drivers/net/phy/phy.c @@ -146,7 +146,7 @@ static int phy_config_interrupt(struct phy_device *phydev, u32 interrupts) */ int phy_aneg_done(struct phy_device *phydev) { - if (phydev->drv->aneg_done) + if (phydev->drv && phydev->drv->aneg_done) return phydev->drv->aneg_done(phydev); return genphy_aneg_done(phydev); diff --git a/drivers/net/usb/kalmia.c b/drivers/net/usb/kalmia.c index 3e37724d30ae..8aefb282c862 100644 --- a/drivers/net/usb/kalmia.c +++ b/drivers/net/usb/kalmia.c @@ -343,7 +343,7 @@ static const struct driver_info kalmia_info = { static const struct usb_device_id products[] = { /* The unswitched USB ID, to get the module auto loaded: */ { USB_DEVICE(0x04e8, 0x689a) }, - /* The stick swithed into modem (by e.g. usb_modeswitch): */ + /* The stick switched into modem (by e.g. usb_modeswitch): */ { USB_DEVICE(0x04e8, 0x6889), .driver_info = (unsigned long) &kalmia_info, }, { /* EMPTY == end of list */} }; diff --git a/drivers/net/usb/rndis_host.c b/drivers/net/usb/rndis_host.c index 4f4f71b2966b..c5b21138b7eb 100644 --- a/drivers/net/usb/rndis_host.c +++ b/drivers/net/usb/rndis_host.c @@ -383,7 +383,7 @@ generic_rndis_bind(struct usbnet *dev, struct usb_interface *intf, int flags) /* REVISIT: peripheral "alignment" request is ignored ... */ dev_dbg(&intf->dev, - "hard mtu %u (%u from dev), rx buflen %Zu, align %d\n", + "hard mtu %u (%u from dev), rx buflen %zu, align %d\n", dev->hard_mtu, tmp, dev->rx_urb_size, 1 << le32_to_cpu(u.init_c->packet_alignment)); diff --git a/drivers/net/usb/sierra_net.c b/drivers/net/usb/sierra_net.c index d9440bc022f2..ac69f28d92d2 100644 --- a/drivers/net/usb/sierra_net.c +++ b/drivers/net/usb/sierra_net.c @@ -379,7 +379,7 @@ static int sierra_net_parse_lsi(struct usbnet *dev, char *data, int datalen) u32 expected_length; if (datalen < sizeof(struct lsi_umts_single)) { - netdev_err(dev->net, "%s: Data length %d, exp >= %Zu\n", + netdev_err(dev->net, "%s: Data length %d, exp >= %zu\n", __func__, datalen, sizeof(struct lsi_umts_single)); return -1; } diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c index 556953f53437..b7911994112a 100644 --- a/drivers/net/vxlan.c +++ b/drivers/net/vxlan.c @@ -2035,7 +2035,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, const struct iphdr *old_iph = ip_hdr(skb); union vxlan_addr *dst; union vxlan_addr remote_ip, local_ip; - union vxlan_addr *src; struct vxlan_metadata _md; struct vxlan_metadata *md = &_md; __be16 src_port = 0, dst_port; @@ -2062,7 +2061,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, dst_port = rdst->remote_port ? rdst->remote_port : vxlan->cfg.dst_port; vni = (rdst->remote_vni) ? : default_vni; - src = &vxlan->cfg.saddr; + local_ip = vxlan->cfg.saddr; dst_cache = &rdst->dst_cache; md->gbp = skb->mark; ttl = vxlan->cfg.ttl; @@ -2095,7 +2094,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, dst = &remote_ip; dst_port = info->key.tp_dst ? : vxlan->cfg.dst_port; vni = tunnel_id_to_key32(info->key.tun_id); - src = &local_ip; dst_cache = &info->dst_cache; if (info->options_len) md = ip_tunnel_info_opts(info); @@ -2115,7 +2113,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, rt = vxlan_get_route(vxlan, dev, sock4, skb, rdst ? rdst->remote_ifindex : 0, tos, dst->sin.sin_addr.s_addr, - &src->sin.sin_addr.s_addr, + &local_ip.sin.sin_addr.s_addr, dst_port, src_port, dst_cache, info); if (IS_ERR(rt)) { @@ -2142,7 +2140,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, if (err < 0) goto tx_error; - udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, src->sin.sin_addr.s_addr, + udp_tunnel_xmit_skb(rt, sock4->sock->sk, skb, local_ip.sin.sin_addr.s_addr, dst->sin.sin_addr.s_addr, tos, ttl, df, src_port, dst_port, xnet, !udp_sum); #if IS_ENABLED(CONFIG_IPV6) @@ -2152,7 +2150,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, ndst = vxlan6_get_route(vxlan, dev, sock6, skb, rdst ? rdst->remote_ifindex : 0, tos, label, &dst->sin6.sin6_addr, - &src->sin6.sin6_addr, + &local_ip.sin6.sin6_addr, dst_port, src_port, dst_cache, info); if (IS_ERR(ndst)) { @@ -2180,7 +2178,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev, goto tx_error; udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev, - &src->sin6.sin6_addr, + &local_ip.sin6.sin6_addr, &dst->sin6.sin6_addr, tos, ttl, label, src_port, dst_port, !udp_sum); #endif @@ -2675,7 +2673,7 @@ static int vxlan_validate(struct nlattr *tb[], struct nlattr *data[]) if (data[IFLA_VXLAN_ID]) { __u32 id = nla_get_u32(data[IFLA_VXLAN_ID]); - if (id >= VXLAN_VID_MASK) + if (id >= VXLAN_N_VID) return -ERANGE; } diff --git a/drivers/net/wimax/i2400m/usb-fw.c b/drivers/net/wimax/i2400m/usb-fw.c index e74664b84925..502c346aa790 100644 --- a/drivers/net/wimax/i2400m/usb-fw.c +++ b/drivers/net/wimax/i2400m/usb-fw.c @@ -237,7 +237,7 @@ void __i2400mu_bm_notif_cb(struct urb *urb) * * @i2400m: device descriptor * @urb: urb to use - * @completion: completion varible to complete when done + * @completion: completion variable to complete when done * * Data is always read to i2400m->bm_ack_buf */ diff --git a/drivers/net/wireless/ath/ath9k/ani.c b/drivers/net/wireless/ath/ath9k/ani.c index 815efe9fd208..5214dd7a3936 100644 --- a/drivers/net/wireless/ath/ath9k/ani.c +++ b/drivers/net/wireless/ath/ath9k/ani.c @@ -59,13 +59,13 @@ static const struct ani_ofdm_level_entry ofdm_level_table[] = { /* * MRC (Maximal Ratio Combining) has always been used with multi-antenna ofdm. * With OFDM for single stream you just add up all antenna inputs, you're - * only interested in what you get after FFT. Signal aligment is also not + * only interested in what you get after FFT. Signal alignment is also not * required for OFDM because any phase difference adds up in the frequency * domain. * * MRC requires extra work for use with CCK. You need to align the antenna * signals from the different antenna before you can add the signals together. - * You need aligment of signals as CCK is in time domain, so addition can cancel + * You need alignment of signals as CCK is in time domain, so addition can cancel * your signal completely if phase is 180 degrees (think of adding sine waves). * You also need to remove noise before the addition and this is where ANI * MRC CCK comes into play. One of the antenna inputs may be stronger but diff --git a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c index 10098b7586f3..944b83cfc519 100644 --- a/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c +++ b/drivers/net/wireless/broadcom/brcm80211/brcmfmac/cfg80211.c @@ -4874,7 +4874,7 @@ brcmf_cfg80211_mgmt_tx(struct wiphy *wiphy, struct wireless_dev *wdev, kfree(af_params); } else { brcmf_dbg(TRACE, "Unhandled, fc=%04x!!\n", mgmt->frame_control); - brcmf_dbg_hex_dump(true, buf, len, "payload, len=%Zu\n", len); + brcmf_dbg_hex_dump(true, buf, len, "payload, len=%zu\n", len); } exit: diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2100.c b/drivers/net/wireless/intel/ipw2x00/ipw2100.c index 356aba9d3d53..f922859acf40 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2100.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2100.c @@ -1238,7 +1238,7 @@ static int ipw2100_get_hw_features(struct ipw2100_priv *priv) } /* - * Start firmware execution after power on and intialization + * Start firmware execution after power on and initialization * The sequence is: * 1. Release ARC * 2. Wait for f/w initialization completes; @@ -1277,7 +1277,7 @@ static int ipw2100_start_adapter(struct ipw2100_priv *priv) /* Release ARC - clear reset bit */ write_register(priv->net_dev, IPW_REG_RESET_REG, 0); - /* wait for f/w intialization complete */ + /* wait for f/w initialization complete */ IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n"); i = 5000; do { @@ -5652,7 +5652,7 @@ static void shim__set_security(struct net_device *dev, /* As a temporary work around to enable WPA until we figure out why * wpa_supplicant toggles the security capability of the driver, which - * forces a disassocation with force_update... + * forces a disassociation with force_update... * * if (force_update || !(priv->status & STATUS_ASSOCIATED))*/ if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) diff --git a/drivers/net/wireless/intel/ipw2x00/ipw2200.c b/drivers/net/wireless/intel/ipw2x00/ipw2200.c index ef9af8a29cad..5ef3c5cc47c5 100644 --- a/drivers/net/wireless/intel/ipw2x00/ipw2200.c +++ b/drivers/net/wireless/intel/ipw2x00/ipw2200.c @@ -3974,7 +3974,7 @@ static void ipw_send_disassociate(struct ipw_priv *priv, int quiet) return; } - IPW_DEBUG_ASSOC("Disassocation attempt from %pM " + IPW_DEBUG_ASSOC("Disassociation attempt from %pM " "on channel %d.\n", priv->assoc_request.bssid, priv->assoc_request.channel); @@ -5196,7 +5196,7 @@ static void ipw_rx_queue_restock(struct ipw_priv *priv) * Move all used packet from rx_used to rx_free, allocating a new SKB for each. * Also restock the Rx queue via ipw_rx_queue_restock. * - * This is called as a scheduled work item (except for during intialization) + * This is called as a scheduled work item (except for during initialization) */ static void ipw_rx_queue_replenish(void *data) { diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c b/drivers/net/wireless/intel/iwlegacy/4965-mac.c index a91d170a614b..2781f5728d07 100644 --- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c +++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c @@ -4855,39 +4855,39 @@ il4965_ucode_callback(const struct firmware *ucode_raw, void *context) */ D_INFO("f/w package hdr ucode version raw = 0x%x\n", il->ucode_ver); - D_INFO("f/w package hdr runtime inst size = %Zd\n", pieces.inst_size); - D_INFO("f/w package hdr runtime data size = %Zd\n", pieces.data_size); - D_INFO("f/w package hdr init inst size = %Zd\n", pieces.init_size); - D_INFO("f/w package hdr init data size = %Zd\n", pieces.init_data_size); - D_INFO("f/w package hdr boot inst size = %Zd\n", pieces.boot_size); + D_INFO("f/w package hdr runtime inst size = %zd\n", pieces.inst_size); + D_INFO("f/w package hdr runtime data size = %zd\n", pieces.data_size); + D_INFO("f/w package hdr init inst size = %zd\n", pieces.init_size); + D_INFO("f/w package hdr init data size = %zd\n", pieces.init_data_size); + D_INFO("f/w package hdr boot inst size = %zd\n", pieces.boot_size); /* Verify that uCode images will fit in card's SRAM */ if (pieces.inst_size > il->hw_params.max_inst_size) { - IL_ERR("uCode instr len %Zd too large to fit in\n", + IL_ERR("uCode instr len %zd too large to fit in\n", pieces.inst_size); goto try_again; } if (pieces.data_size > il->hw_params.max_data_size) { - IL_ERR("uCode data len %Zd too large to fit in\n", + IL_ERR("uCode data len %zd too large to fit in\n", pieces.data_size); goto try_again; } if (pieces.init_size > il->hw_params.max_inst_size) { - IL_ERR("uCode init instr len %Zd too large to fit in\n", + IL_ERR("uCode init instr len %zd too large to fit in\n", pieces.init_size); goto try_again; } if (pieces.init_data_size > il->hw_params.max_data_size) { - IL_ERR("uCode init data len %Zd too large to fit in\n", + IL_ERR("uCode init data len %zd too large to fit in\n", pieces.init_data_size); goto try_again; } if (pieces.boot_size > il->hw_params.max_bsm_size) { - IL_ERR("uCode boot instr len %Zd too large to fit in\n", + IL_ERR("uCode boot instr len %zd too large to fit in\n", pieces.boot_size); goto try_again; } @@ -4938,7 +4938,7 @@ il4965_ucode_callback(const struct firmware *ucode_raw, void *context) /* Copy images into buffers for card's bus-master reads ... */ /* Runtime instructions (first block of data in file) */ - D_INFO("Copying (but not loading) uCode instr len %Zd\n", + D_INFO("Copying (but not loading) uCode instr len %zd\n", pieces.inst_size); memcpy(il->ucode_code.v_addr, pieces.inst, pieces.inst_size); @@ -4949,28 +4949,28 @@ il4965_ucode_callback(const struct firmware *ucode_raw, void *context) * Runtime data * NOTE: Copy into backup buffer will be done in il_up() */ - D_INFO("Copying (but not loading) uCode data len %Zd\n", + D_INFO("Copying (but not loading) uCode data len %zd\n", pieces.data_size); memcpy(il->ucode_data.v_addr, pieces.data, pieces.data_size); memcpy(il->ucode_data_backup.v_addr, pieces.data, pieces.data_size); /* Initialization instructions */ if (pieces.init_size) { - D_INFO("Copying (but not loading) init instr len %Zd\n", + D_INFO("Copying (but not loading) init instr len %zd\n", pieces.init_size); memcpy(il->ucode_init.v_addr, pieces.init, pieces.init_size); } /* Initialization data */ if (pieces.init_data_size) { - D_INFO("Copying (but not loading) init data len %Zd\n", + D_INFO("Copying (but not loading) init data len %zd\n", pieces.init_data_size); memcpy(il->ucode_init_data.v_addr, pieces.init_data, pieces.init_data_size); } /* Bootstrap instructions */ - D_INFO("Copying (but not loading) boot instr len %Zd\n", + D_INFO("Copying (but not loading) boot instr len %zd\n", pieces.boot_size); memcpy(il->ucode_boot.v_addr, pieces.boot, pieces.boot_size); diff --git a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c index 0e0293d42b5d..be466a074c1d 100644 --- a/drivers/net/wireless/intel/iwlwifi/iwl-drv.c +++ b/drivers/net/wireless/intel/iwlwifi/iwl-drv.c @@ -1141,21 +1141,21 @@ static int validate_sec_sizes(struct iwl_drv *drv, struct iwl_firmware_pieces *pieces, const struct iwl_cfg *cfg) { - IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %Zd\n", + IWL_DEBUG_INFO(drv, "f/w package hdr runtime inst size = %zd\n", get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST)); - IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %Zd\n", + IWL_DEBUG_INFO(drv, "f/w package hdr runtime data size = %zd\n", get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA)); - IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %Zd\n", + IWL_DEBUG_INFO(drv, "f/w package hdr init inst size = %zd\n", get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); - IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %Zd\n", + IWL_DEBUG_INFO(drv, "f/w package hdr init data size = %zd\n", get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA)); /* Verify that uCode images will fit in card's SRAM. */ if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST) > cfg->max_inst_size) { - IWL_ERR(drv, "uCode instr len %Zd too large to fit in\n", + IWL_ERR(drv, "uCode instr len %zd too large to fit in\n", get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_INST)); return -1; @@ -1163,7 +1163,7 @@ static int validate_sec_sizes(struct iwl_drv *drv, if (get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA) > cfg->max_data_size) { - IWL_ERR(drv, "uCode data len %Zd too large to fit in\n", + IWL_ERR(drv, "uCode data len %zd too large to fit in\n", get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA)); return -1; @@ -1171,7 +1171,7 @@ static int validate_sec_sizes(struct iwl_drv *drv, if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST) > cfg->max_inst_size) { - IWL_ERR(drv, "uCode init instr len %Zd too large to fit in\n", + IWL_ERR(drv, "uCode init instr len %zd too large to fit in\n", get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_INST)); return -1; @@ -1179,7 +1179,7 @@ static int validate_sec_sizes(struct iwl_drv *drv, if (get_sec_size(pieces, IWL_UCODE_INIT, IWL_UCODE_SECTION_DATA) > cfg->max_data_size) { - IWL_ERR(drv, "uCode init data len %Zd too large to fit in\n", + IWL_ERR(drv, "uCode init data len %zd too large to fit in\n", get_sec_size(pieces, IWL_UCODE_REGULAR, IWL_UCODE_SECTION_DATA)); return -1; diff --git a/drivers/net/wireless/marvell/mwifiex/txrx.c b/drivers/net/wireless/marvell/mwifiex/txrx.c index abdd0cf710bf..fac28bd8fbee 100644 --- a/drivers/net/wireless/marvell/mwifiex/txrx.c +++ b/drivers/net/wireless/marvell/mwifiex/txrx.c @@ -346,9 +346,7 @@ void mwifiex_parse_tx_status_event(struct mwifiex_private *priv, return; spin_lock_irqsave(&priv->ack_status_lock, flags); - ack_skb = idr_find(&priv->ack_status_frames, tx_status->tx_token_id); - if (ack_skb) - idr_remove(&priv->ack_status_frames, tx_status->tx_token_id); + ack_skb = idr_remove(&priv->ack_status_frames, tx_status->tx_token_id); spin_unlock_irqrestore(&priv->ack_status_lock, flags); if (ack_skb) { diff --git a/drivers/net/wireless/marvell/mwifiex/wmm.c b/drivers/net/wireless/marvell/mwifiex/wmm.c index 28c2f6fae3e6..e4ff3b973850 100644 --- a/drivers/net/wireless/marvell/mwifiex/wmm.c +++ b/drivers/net/wireless/marvell/mwifiex/wmm.c @@ -673,8 +673,8 @@ void mwifiex_update_ralist_tx_pause(struct mwifiex_private *priv, u8 *mac, spin_unlock_irqrestore(&priv->wmm.ra_list_spinlock, flags); } -/* This function update non-tdls peer ralist tx_pause while - * tdls channel swithing +/* This function updates non-tdls peer ralist tx_pause while + * tdls channel switching */ void mwifiex_update_ralist_tx_pause_in_tdls_cs(struct mwifiex_private *priv, u8 *mac, u8 tx_pause) diff --git a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c index 1922e78ad6bd..89a0a28b8b20 100644 --- a/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c +++ b/drivers/net/wireless/realtek/rtlwifi/rtl8192se/fw.c @@ -455,7 +455,7 @@ static u32 _rtl92s_fill_h2c_cmd(struct sk_buff *skb, u32 h2cbufferlen, u8 i = 0; do { - /* 8 - Byte aligment */ + /* 8 - Byte alignment */ len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8); /* Buffer length is not enough */ @@ -504,7 +504,7 @@ static u32 _rtl92s_get_h2c_cmdlen(u32 h2cbufferlen, u32 cmd_num, u32 *pcmd_len) u8 i = 0; do { - /* 8 - Byte aligment */ + /* 8 - Byte alignment */ len = H2C_TX_CMD_HDR_LEN + N_BYTE_ALIGMENT(pcmd_len[i], 8); /* Buffer length is not enough */ diff --git a/drivers/net/wireless/rsi/rsi_91x_usb.c b/drivers/net/wireless/rsi/rsi_91x_usb.c index ef5d394f185b..cc8deecea8cb 100644 --- a/drivers/net/wireless/rsi/rsi_91x_usb.c +++ b/drivers/net/wireless/rsi/rsi_91x_usb.c @@ -516,7 +516,7 @@ err: /** * rsi_disconnect() - This function performs the reverse of the probe function, - * it deintialize the driver structure. + * it deinitialize the driver structure. * @pfunction: Pointer to the USB interface structure. * * Return: None. diff --git a/drivers/net/wireless/ti/wl18xx/main.c b/drivers/net/wireless/ti/wl18xx/main.c index 5bdf7a03e3dd..d1aa3eee0e81 100644 --- a/drivers/net/wireless/ti/wl18xx/main.c +++ b/drivers/net/wireless/ti/wl18xx/main.c @@ -178,7 +178,7 @@ static struct wlcore_conf wl18xx_conf = { .sg = { .params = { [WL18XX_CONF_SG_PARAM_0] = 0, - /* Configuartion Parameters */ + /* Configuration Parameters */ [WL18XX_CONF_SG_ANTENNA_CONFIGURATION] = 0, [WL18XX_CONF_SG_ZIGBEE_COEX] = 0, [WL18XX_CONF_SG_TIME_SYNC] = 0, diff --git a/drivers/net/wireless/ti/wlcore/init.c b/drivers/net/wireless/ti/wlcore/init.c index d0b7734030ef..58898b99d3f7 100644 --- a/drivers/net/wireless/ti/wlcore/init.c +++ b/drivers/net/wireless/ti/wlcore/init.c @@ -544,7 +544,7 @@ static int wl12xx_init_sta_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) return 0; } -/* vif-specific intialization */ +/* vif-specific initialization */ static int wl12xx_init_ap_role(struct wl1271 *wl, struct wl12xx_vif *wlvif) { int ret; diff --git a/drivers/nfc/pn533/pn533.c b/drivers/nfc/pn533/pn533.c index d9c55830b2b2..a966c6a85ea8 100644 --- a/drivers/nfc/pn533/pn533.c +++ b/drivers/nfc/pn533/pn533.c @@ -487,7 +487,7 @@ static int pn533_send_cmd_async(struct pn533 *dev, u8 cmd_code, /* * pn533_send_cmd_direct_async * - * The function sends a piority cmd directly to the chip omiting the cmd + * The function sends a piority cmd directly to the chip omitting the cmd * queue. It's intended to be used by chaining mechanism of received responses * where the host has to request every single chunk of data before scheduling * next cmd from the queue. diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c index bc20a2442a04..779f516e7a4e 100644 --- a/drivers/nvme/host/rdma.c +++ b/drivers/nvme/host/rdma.c @@ -1051,7 +1051,7 @@ static int nvme_rdma_post_send(struct nvme_rdma_queue *queue, * sequencer is not allocated in our driver's tagset and it's * triggered to be freed by blk_cleanup_queue(). So we need to * always mark it as signaled to ensure that the "wr_cqe", which is - * embeded in request's payload, is not freed when __ib_process_cq() + * embedded in request's payload, is not freed when __ib_process_cq() * calls wr_cqe->done(). */ if ((++queue->sig_count % 32) == 0 || flush) diff --git a/drivers/parport/ieee1284_ops.c b/drivers/parport/ieee1284_ops.c index c0e7d21c88c2..75071605d22f 100644 --- a/drivers/parport/ieee1284_ops.c +++ b/drivers/parport/ieee1284_ops.c @@ -307,7 +307,7 @@ size_t parport_ieee1284_read_byte (struct parport *port, if (parport_read_status (port) & PARPORT_STATUS_ERROR) { end_of_data: DPRINTK (KERN_DEBUG - "%s: No more byte data (%Zd bytes)\n", + "%s: No more byte data (%zd bytes)\n", port->name, count); /* Go to reverse idle phase. */ diff --git a/drivers/parport/parport_pc.c b/drivers/parport/parport_pc.c index 78530d1714dc..3e56e7deab8e 100644 --- a/drivers/parport/parport_pc.c +++ b/drivers/parport/parport_pc.c @@ -902,7 +902,7 @@ static size_t parport_pc_ecp_write_block_pio(struct parport *port, * ****************************************** */ -/* GCC is not inlining extern inline function later overwriten to non-inline, +/* GCC is not inlining extern inline function later overwritten to non-inline, so we use outlined_ variants here. */ static const struct parport_operations parport_pc_ops = { .write_data = parport_pc_write_data, diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c index ca77d235867f..f754453fe754 100644 --- a/drivers/pci/quirks.c +++ b/drivers/pci/quirks.c @@ -3630,7 +3630,7 @@ static int __init pci_apply_final_quirks(void) fs_initcall_sync(pci_apply_final_quirks); /* - * Followings are device-specific reset methods which can be used to + * Following are device-specific reset methods which can be used to * reset a single function if other methods (e.g. FLR, PM D0->D3) are * not available. */ diff --git a/drivers/pinctrl/bcm/Kconfig b/drivers/pinctrl/bcm/Kconfig index 8968dd7aebed..e8c4e4f934a6 100644 --- a/drivers/pinctrl/bcm/Kconfig +++ b/drivers/pinctrl/bcm/Kconfig @@ -70,7 +70,7 @@ config PINCTRL_CYGNUS_MUX The Broadcom Cygnus IOMUX driver supports group based IOMUX configuration, with the exception that certain individual pins - can be overrided to GPIO function + can be overridden to GPIO function config PINCTRL_NSP_GPIO bool "Broadcom NSP GPIO (with PINCONF) driver" diff --git a/drivers/power/avs/smartreflex.c b/drivers/power/avs/smartreflex.c index fa0f19b975a6..974fd684bab2 100644 --- a/drivers/power/avs/smartreflex.c +++ b/drivers/power/avs/smartreflex.c @@ -195,7 +195,7 @@ static void sr_stop_vddautocomp(struct omap_sr *sr) } /* - * This function handles the intializations which have to be done + * This function handles the initializations which have to be done * only when both sr device and class driver regiter has * completed. This will be attempted to be called from both sr class * driver register and sr device intializtion API's. Only one call @@ -671,7 +671,7 @@ int sr_register_class(struct omap_sr_class_data *class_data) sr_class = class_data; /* - * Call into late init to do intializations that require + * Call into late init to do initializations that require * both sr driver and sr class driver to be initiallized. */ list_for_each_entry(sr_info, &sr_list, node) @@ -899,7 +899,7 @@ static int __init omap_sr_probe(struct platform_device *pdev) list_add(&sr_info->node, &sr_list); /* - * Call into late init to do intializations that require + * Call into late init to do initializations that require * both sr driver and sr class driver to be initiallized. */ if (sr_class) { diff --git a/drivers/rapidio/devices/rio_mport_cdev.c b/drivers/rapidio/devices/rio_mport_cdev.c index 9013a585507e..50b617af81bd 100644 --- a/drivers/rapidio/devices/rio_mport_cdev.c +++ b/drivers/rapidio/devices/rio_mport_cdev.c @@ -889,17 +889,16 @@ rio_dma_transfer(struct file *filp, u32 transfer_mode, goto err_req; } - down_read(¤t->mm->mmap_sem); - pinned = get_user_pages( + pinned = get_user_pages_unlocked( (unsigned long)xfer->loc_addr & PAGE_MASK, nr_pages, - dir == DMA_FROM_DEVICE ? FOLL_WRITE : 0, - page_list, NULL); - up_read(¤t->mm->mmap_sem); + page_list, + dir == DMA_FROM_DEVICE ? FOLL_WRITE : 0); if (pinned != nr_pages) { if (pinned < 0) { - rmcd_error("get_user_pages err=%ld", pinned); + rmcd_error("get_user_pages_unlocked err=%ld", + pinned); nr_pages = 0; } else rmcd_error("pinned %ld out of %ld pages", diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig index 5dc673dc9487..ee1b0e9dde79 100644 --- a/drivers/rtc/Kconfig +++ b/drivers/rtc/Kconfig @@ -1434,9 +1434,10 @@ config RTC_DRV_SUN4V based RTC on SUN4V systems. config RTC_DRV_SUN6I - tristate "Allwinner A31 RTC" - default MACH_SUN6I || MACH_SUN8I || COMPILE_TEST - depends on ARCH_SUNXI + bool "Allwinner A31 RTC" + default MACH_SUN6I || MACH_SUN8I + depends on COMMON_CLK + depends on ARCH_SUNXI || COMPILE_TEST help If you say Y here you will get support for the RTC found in some Allwinner SoCs like the A31 or the A64. @@ -1719,6 +1720,17 @@ config RTC_DRV_R7301 This driver can also be built as a module. If so, the module will be called rtc-r7301. +config RTC_DRV_STM32 + tristate "STM32 RTC" + select REGMAP_MMIO + depends on ARCH_STM32 || COMPILE_TEST + help + If you say yes here you get support for the STM32 On-Chip + Real Time Clock. + + This driver can also be built as a module, if so, the module + will be called "rtc-stm32". + comment "HID Sensor RTC drivers" config RTC_DRV_HID_SENSOR_TIME diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index f13ab1c5c222..f07297b1460a 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -145,6 +145,7 @@ obj-$(CONFIG_RTC_DRV_SNVS) += rtc-snvs.o obj-$(CONFIG_RTC_DRV_SPEAR) += rtc-spear.o obj-$(CONFIG_RTC_DRV_STARFIRE) += rtc-starfire.o obj-$(CONFIG_RTC_DRV_STK17TA8) += rtc-stk17ta8.o +obj-$(CONFIG_RTC_DRV_STM32) += rtc-stm32.o obj-$(CONFIG_RTC_DRV_STMP) += rtc-stmp3xxx.o obj-$(CONFIG_RTC_DRV_ST_LPC) += rtc-st-lpc.o obj-$(CONFIG_RTC_DRV_SUN4V) += rtc-sun4v.o diff --git a/drivers/rtc/rtc-armada38x.c b/drivers/rtc/rtc-armada38x.c index 9a3f2a6f512e..21f355c37eab 100644 --- a/drivers/rtc/rtc-armada38x.c +++ b/drivers/rtc/rtc-armada38x.c @@ -16,6 +16,7 @@ #include <linux/io.h> #include <linux/module.h> #include <linux/of.h> +#include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/rtc.h> @@ -23,17 +24,48 @@ #define RTC_STATUS_ALARM1 BIT(0) #define RTC_STATUS_ALARM2 BIT(1) #define RTC_IRQ1_CONF 0x4 -#define RTC_IRQ1_AL_EN BIT(0) -#define RTC_IRQ1_FREQ_EN BIT(1) -#define RTC_IRQ1_FREQ_1HZ BIT(2) +#define RTC_IRQ2_CONF 0x8 +#define RTC_IRQ_AL_EN BIT(0) +#define RTC_IRQ_FREQ_EN BIT(1) +#define RTC_IRQ_FREQ_1HZ BIT(2) + #define RTC_TIME 0xC #define RTC_ALARM1 0x10 - -#define SOC_RTC_INTERRUPT 0x8 -#define SOC_RTC_ALARM1 BIT(0) -#define SOC_RTC_ALARM2 BIT(1) -#define SOC_RTC_ALARM1_MASK BIT(2) -#define SOC_RTC_ALARM2_MASK BIT(3) +#define RTC_ALARM2 0x14 + +/* Armada38x SoC registers */ +#define RTC_38X_BRIDGE_TIMING_CTL 0x0 +#define RTC_38X_PERIOD_OFFS 0 +#define RTC_38X_PERIOD_MASK (0x3FF << RTC_38X_PERIOD_OFFS) +#define RTC_38X_READ_DELAY_OFFS 26 +#define RTC_38X_READ_DELAY_MASK (0x1F << RTC_38X_READ_DELAY_OFFS) + +/* Armada 7K/8K registers */ +#define RTC_8K_BRIDGE_TIMING_CTL0 0x0 +#define RTC_8K_WRCLK_PERIOD_OFFS 0 +#define RTC_8K_WRCLK_PERIOD_MASK (0xFFFF << RTC_8K_WRCLK_PERIOD_OFFS) +#define RTC_8K_WRCLK_SETUP_OFFS 16 +#define RTC_8K_WRCLK_SETUP_MASK (0xFFFF << RTC_8K_WRCLK_SETUP_OFFS) +#define RTC_8K_BRIDGE_TIMING_CTL1 0x4 +#define RTC_8K_READ_DELAY_OFFS 0 +#define RTC_8K_READ_DELAY_MASK (0xFFFF << RTC_8K_READ_DELAY_OFFS) + +#define RTC_8K_ISR 0x10 +#define RTC_8K_IMR 0x14 +#define RTC_8K_ALARM2 BIT(0) + +#define SOC_RTC_INTERRUPT 0x8 +#define SOC_RTC_ALARM1 BIT(0) +#define SOC_RTC_ALARM2 BIT(1) +#define SOC_RTC_ALARM1_MASK BIT(2) +#define SOC_RTC_ALARM2_MASK BIT(3) + +#define SAMPLE_NR 100 + +struct value_to_freq { + u32 value; + u8 freq; +}; struct armada38x_rtc { struct rtc_device *rtc_dev; @@ -41,38 +73,153 @@ struct armada38x_rtc { void __iomem *regs_soc; spinlock_t lock; int irq; + struct value_to_freq *val_to_freq; + struct armada38x_rtc_data *data; +}; + +#define ALARM1 0 +#define ALARM2 1 + +#define ALARM_REG(base, alarm) ((base) + (alarm) * sizeof(u32)) + +struct armada38x_rtc_data { + /* Initialize the RTC-MBUS bridge timing */ + void (*update_mbus_timing)(struct armada38x_rtc *rtc); + u32 (*read_rtc_reg)(struct armada38x_rtc *rtc, u8 rtc_reg); + void (*clear_isr)(struct armada38x_rtc *rtc); + void (*unmask_interrupt)(struct armada38x_rtc *rtc); + u32 alarm; }; /* * According to the datasheet, the OS should wait 5us after every * register write to the RTC hard macro so that the required update * can occur without holding off the system bus + * According to errata RES-3124064, Write to any RTC register + * may fail. As a workaround, before writing to RTC + * register, issue a dummy write of 0x0 twice to RTC Status + * register. */ + static void rtc_delayed_write(u32 val, struct armada38x_rtc *rtc, int offset) { + writel(0, rtc->regs + RTC_STATUS); + writel(0, rtc->regs + RTC_STATUS); writel(val, rtc->regs + offset); udelay(5); } +/* Update RTC-MBUS bridge timing parameters */ +static void rtc_update_38x_mbus_timing_params(struct armada38x_rtc *rtc) +{ + u32 reg; + + reg = readl(rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL); + reg &= ~RTC_38X_PERIOD_MASK; + reg |= 0x3FF << RTC_38X_PERIOD_OFFS; /* Maximum value */ + reg &= ~RTC_38X_READ_DELAY_MASK; + reg |= 0x1F << RTC_38X_READ_DELAY_OFFS; /* Maximum value */ + writel(reg, rtc->regs_soc + RTC_38X_BRIDGE_TIMING_CTL); +} + +static void rtc_update_8k_mbus_timing_params(struct armada38x_rtc *rtc) +{ + u32 reg; + + reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0); + reg &= ~RTC_8K_WRCLK_PERIOD_MASK; + reg |= 0x3FF << RTC_8K_WRCLK_PERIOD_OFFS; + reg &= ~RTC_8K_WRCLK_SETUP_MASK; + reg |= 0x29 << RTC_8K_WRCLK_SETUP_OFFS; + writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL0); + + reg = readl(rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1); + reg &= ~RTC_8K_READ_DELAY_MASK; + reg |= 0x3F << RTC_8K_READ_DELAY_OFFS; + writel(reg, rtc->regs_soc + RTC_8K_BRIDGE_TIMING_CTL1); +} + +static u32 read_rtc_register(struct armada38x_rtc *rtc, u8 rtc_reg) +{ + return readl(rtc->regs + rtc_reg); +} + +static u32 read_rtc_register_38x_wa(struct armada38x_rtc *rtc, u8 rtc_reg) +{ + int i, index_max = 0, max = 0; + + for (i = 0; i < SAMPLE_NR; i++) { + rtc->val_to_freq[i].value = readl(rtc->regs + rtc_reg); + rtc->val_to_freq[i].freq = 0; + } + + for (i = 0; i < SAMPLE_NR; i++) { + int j = 0; + u32 value = rtc->val_to_freq[i].value; + + while (rtc->val_to_freq[j].freq) { + if (rtc->val_to_freq[j].value == value) { + rtc->val_to_freq[j].freq++; + break; + } + j++; + } + + if (!rtc->val_to_freq[j].freq) { + rtc->val_to_freq[j].value = value; + rtc->val_to_freq[j].freq = 1; + } + + if (rtc->val_to_freq[j].freq > max) { + index_max = j; + max = rtc->val_to_freq[j].freq; + } + + /* + * If a value already has half of the sample this is the most + * frequent one and we can stop the research right now + */ + if (max > SAMPLE_NR / 2) + break; + } + + return rtc->val_to_freq[index_max].value; +} + +static void armada38x_clear_isr(struct armada38x_rtc *rtc) +{ + u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); + + writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT); +} + +static void armada38x_unmask_interrupt(struct armada38x_rtc *rtc) +{ + u32 val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); + + writel(val | SOC_RTC_ALARM1_MASK, rtc->regs_soc + SOC_RTC_INTERRUPT); +} + +static void armada8k_clear_isr(struct armada38x_rtc *rtc) +{ + writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_ISR); +} + +static void armada8k_unmask_interrupt(struct armada38x_rtc *rtc) +{ + writel(RTC_8K_ALARM2, rtc->regs_soc + RTC_8K_IMR); +} + static int armada38x_rtc_read_time(struct device *dev, struct rtc_time *tm) { struct armada38x_rtc *rtc = dev_get_drvdata(dev); - unsigned long time, time_check, flags; + unsigned long time, flags; spin_lock_irqsave(&rtc->lock, flags); - time = readl(rtc->regs + RTC_TIME); - /* - * WA for failing time set attempts. As stated in HW ERRATA if - * more than one second between two time reads is detected - * then read once again. - */ - time_check = readl(rtc->regs + RTC_TIME); - if ((time_check - time) > 1) - time_check = readl(rtc->regs + RTC_TIME); - + time = rtc->data->read_rtc_reg(rtc, RTC_TIME); spin_unlock_irqrestore(&rtc->lock, flags); - rtc_time_to_tm(time_check, tm); + rtc_time_to_tm(time, tm); return 0; } @@ -87,16 +234,9 @@ static int armada38x_rtc_set_time(struct device *dev, struct rtc_time *tm) if (ret) goto out; - /* - * According to errata FE-3124064, Write to RTC TIME register - * may fail. As a workaround, after writing to RTC TIME - * register, issue a dummy write of 0x0 twice to RTC Status - * register. - */ + spin_lock_irqsave(&rtc->lock, flags); rtc_delayed_write(time, rtc, RTC_TIME); - rtc_delayed_write(0, rtc, RTC_STATUS); - rtc_delayed_write(0, rtc, RTC_STATUS); spin_unlock_irqrestore(&rtc->lock, flags); out: @@ -107,12 +247,14 @@ static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct armada38x_rtc *rtc = dev_get_drvdata(dev); unsigned long time, flags; + u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm); + u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); u32 val; spin_lock_irqsave(&rtc->lock, flags); - time = readl(rtc->regs + RTC_ALARM1); - val = readl(rtc->regs + RTC_IRQ1_CONF) & RTC_IRQ1_AL_EN; + time = rtc->data->read_rtc_reg(rtc, reg); + val = rtc->data->read_rtc_reg(rtc, reg_irq) & RTC_IRQ_AL_EN; spin_unlock_irqrestore(&rtc->lock, flags); @@ -125,9 +267,10 @@ static int armada38x_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) { struct armada38x_rtc *rtc = dev_get_drvdata(dev); + u32 reg = ALARM_REG(RTC_ALARM1, rtc->data->alarm); + u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); unsigned long time, flags; int ret = 0; - u32 val; ret = rtc_tm_to_time(&alrm->time, &time); @@ -136,13 +279,11 @@ static int armada38x_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) spin_lock_irqsave(&rtc->lock, flags); - rtc_delayed_write(time, rtc, RTC_ALARM1); + rtc_delayed_write(time, rtc, reg); if (alrm->enabled) { - rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF); - val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); - writel(val | SOC_RTC_ALARM1_MASK, - rtc->regs_soc + SOC_RTC_INTERRUPT); + rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq); + rtc->data->unmask_interrupt(rtc); } spin_unlock_irqrestore(&rtc->lock, flags); @@ -155,14 +296,15 @@ static int armada38x_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) { struct armada38x_rtc *rtc = dev_get_drvdata(dev); + u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); unsigned long flags; spin_lock_irqsave(&rtc->lock, flags); if (enabled) - rtc_delayed_write(RTC_IRQ1_AL_EN, rtc, RTC_IRQ1_CONF); + rtc_delayed_write(RTC_IRQ_AL_EN, rtc, reg_irq); else - rtc_delayed_write(0, rtc, RTC_IRQ1_CONF); + rtc_delayed_write(0, rtc, reg_irq); spin_unlock_irqrestore(&rtc->lock, flags); @@ -174,24 +316,23 @@ static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data) struct armada38x_rtc *rtc = data; u32 val; int event = RTC_IRQF | RTC_AF; + u32 reg_irq = ALARM_REG(RTC_IRQ1_CONF, rtc->data->alarm); dev_dbg(&rtc->rtc_dev->dev, "%s:irq(%d)\n", __func__, irq); spin_lock(&rtc->lock); - val = readl(rtc->regs_soc + SOC_RTC_INTERRUPT); - - writel(val & ~SOC_RTC_ALARM1, rtc->regs_soc + SOC_RTC_INTERRUPT); - val = readl(rtc->regs + RTC_IRQ1_CONF); - /* disable all the interrupts for alarm 1 */ - rtc_delayed_write(0, rtc, RTC_IRQ1_CONF); + rtc->data->clear_isr(rtc); + val = rtc->data->read_rtc_reg(rtc, reg_irq); + /* disable all the interrupts for alarm*/ + rtc_delayed_write(0, rtc, reg_irq); /* Ack the event */ - rtc_delayed_write(RTC_STATUS_ALARM1, rtc, RTC_STATUS); + rtc_delayed_write(1 << rtc->data->alarm, rtc, RTC_STATUS); spin_unlock(&rtc->lock); - if (val & RTC_IRQ1_FREQ_EN) { - if (val & RTC_IRQ1_FREQ_1HZ) + if (val & RTC_IRQ_FREQ_EN) { + if (val & RTC_IRQ_FREQ_1HZ) event |= RTC_UF; else event |= RTC_PF; @@ -202,7 +343,7 @@ static irqreturn_t armada38x_rtc_alarm_irq(int irq, void *data) return IRQ_HANDLED; } -static struct rtc_class_ops armada38x_rtc_ops = { +static const struct rtc_class_ops armada38x_rtc_ops = { .read_time = armada38x_rtc_read_time, .set_time = armada38x_rtc_set_time, .read_alarm = armada38x_rtc_read_alarm, @@ -210,17 +351,65 @@ static struct rtc_class_ops armada38x_rtc_ops = { .alarm_irq_enable = armada38x_rtc_alarm_irq_enable, }; +static const struct rtc_class_ops armada38x_rtc_ops_noirq = { + .read_time = armada38x_rtc_read_time, + .set_time = armada38x_rtc_set_time, + .read_alarm = armada38x_rtc_read_alarm, +}; + +static const struct armada38x_rtc_data armada38x_data = { + .update_mbus_timing = rtc_update_38x_mbus_timing_params, + .read_rtc_reg = read_rtc_register_38x_wa, + .clear_isr = armada38x_clear_isr, + .unmask_interrupt = armada38x_unmask_interrupt, + .alarm = ALARM1, +}; + +static const struct armada38x_rtc_data armada8k_data = { + .update_mbus_timing = rtc_update_8k_mbus_timing_params, + .read_rtc_reg = read_rtc_register, + .clear_isr = armada8k_clear_isr, + .unmask_interrupt = armada8k_unmask_interrupt, + .alarm = ALARM2, +}; + +#ifdef CONFIG_OF +static const struct of_device_id armada38x_rtc_of_match_table[] = { + { + .compatible = "marvell,armada-380-rtc", + .data = &armada38x_data, + }, + { + .compatible = "marvell,armada-8k-rtc", + .data = &armada8k_data, + }, + {} +}; +MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table); +#endif + static __init int armada38x_rtc_probe(struct platform_device *pdev) { + const struct rtc_class_ops *ops; struct resource *res; struct armada38x_rtc *rtc; + const struct of_device_id *match; int ret; + match = of_match_device(armada38x_rtc_of_match_table, &pdev->dev); + if (!match) + return -ENODEV; + rtc = devm_kzalloc(&pdev->dev, sizeof(struct armada38x_rtc), GFP_KERNEL); if (!rtc) return -ENOMEM; + rtc->val_to_freq = devm_kcalloc(&pdev->dev, SAMPLE_NR, + sizeof(struct value_to_freq), GFP_KERNEL); + if (!rtc->val_to_freq) + return -ENOMEM; + spin_lock_init(&rtc->lock); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rtc"); @@ -242,19 +431,27 @@ static __init int armada38x_rtc_probe(struct platform_device *pdev) 0, pdev->name, rtc) < 0) { dev_warn(&pdev->dev, "Interrupt not available.\n"); rtc->irq = -1; + } + platform_set_drvdata(pdev, rtc); + + if (rtc->irq != -1) { + device_init_wakeup(&pdev->dev, 1); + ops = &armada38x_rtc_ops; + } else { /* * If there is no interrupt available then we can't * use the alarm */ - armada38x_rtc_ops.set_alarm = NULL; - armada38x_rtc_ops.alarm_irq_enable = NULL; + ops = &armada38x_rtc_ops_noirq; } - platform_set_drvdata(pdev, rtc); - if (rtc->irq != -1) - device_init_wakeup(&pdev->dev, 1); + rtc->data = (struct armada38x_rtc_data *)match->data; + + + /* Update RTC-MBUS bridge timing parameters */ + rtc->data->update_mbus_timing(rtc); rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, - &armada38x_rtc_ops, THIS_MODULE); + ops, THIS_MODULE); if (IS_ERR(rtc->rtc_dev)) { ret = PTR_ERR(rtc->rtc_dev); dev_err(&pdev->dev, "Failed to register RTC device: %d\n", ret); @@ -280,6 +477,9 @@ static int armada38x_rtc_resume(struct device *dev) if (device_may_wakeup(dev)) { struct armada38x_rtc *rtc = dev_get_drvdata(dev); + /* Update RTC-MBUS bridge timing parameters */ + rtc->data->update_mbus_timing(rtc); + return disable_irq_wake(rtc->irq); } @@ -290,14 +490,6 @@ static int armada38x_rtc_resume(struct device *dev) static SIMPLE_DEV_PM_OPS(armada38x_rtc_pm_ops, armada38x_rtc_suspend, armada38x_rtc_resume); -#ifdef CONFIG_OF -static const struct of_device_id armada38x_rtc_of_match_table[] = { - { .compatible = "marvell,armada-380-rtc", }, - {} -}; -MODULE_DEVICE_TABLE(of, armada38x_rtc_of_match_table); -#endif - static struct platform_driver armada38x_rtc_driver = { .driver = { .name = "armada38x-rtc", diff --git a/drivers/rtc/rtc-au1xxx.c b/drivers/rtc/rtc-au1xxx.c index 84d6e026784d..2ba44ccb9c3a 100644 --- a/drivers/rtc/rtc-au1xxx.c +++ b/drivers/rtc/rtc-au1xxx.c @@ -56,7 +56,7 @@ static int au1xtoy_rtc_set_time(struct device *dev, struct rtc_time *tm) return 0; } -static struct rtc_class_ops au1xtoy_rtc_ops = { +static const struct rtc_class_ops au1xtoy_rtc_ops = { .read_time = au1xtoy_rtc_read_time, .set_time = au1xtoy_rtc_set_time, }; diff --git a/drivers/rtc/rtc-bfin.c b/drivers/rtc/rtc-bfin.c index 535a5f9338d0..15344b7c07c5 100644 --- a/drivers/rtc/rtc-bfin.c +++ b/drivers/rtc/rtc-bfin.c @@ -333,7 +333,7 @@ static int bfin_rtc_proc(struct device *dev, struct seq_file *seq) #undef yesno } -static struct rtc_class_ops bfin_rtc_ops = { +static const struct rtc_class_ops bfin_rtc_ops = { .read_time = bfin_rtc_read_time, .set_time = bfin_rtc_set_time, .read_alarm = bfin_rtc_read_alarm, diff --git a/drivers/rtc/rtc-bq32k.c b/drivers/rtc/rtc-bq32k.c index 397742446007..2b223935001f 100644 --- a/drivers/rtc/rtc-bq32k.c +++ b/drivers/rtc/rtc-bq32k.c @@ -34,6 +34,7 @@ #define BQ32K_CALIBRATION 0x07 /* CAL_CFG1, calibration and control */ #define BQ32K_TCH2 0x08 /* Trickle charge enable */ #define BQ32K_CFG2 0x09 /* Trickle charger control */ +#define BQ32K_TCFE BIT(6) /* Trickle charge FET bypass */ struct bq32k_regs { uint8_t seconds; @@ -188,6 +189,65 @@ static int trickle_charger_of_init(struct device *dev, struct device_node *node) return 0; } +static ssize_t bq32k_sysfs_show_tricklecharge_bypass(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + int reg, error; + + error = bq32k_read(dev, ®, BQ32K_CFG2, 1); + if (error) + return error; + + return sprintf(buf, "%d\n", (reg & BQ32K_TCFE) ? 1 : 0); +} + +static ssize_t bq32k_sysfs_store_tricklecharge_bypass(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + int reg, enable, error; + + if (kstrtoint(buf, 0, &enable)) + return -EINVAL; + + error = bq32k_read(dev, ®, BQ32K_CFG2, 1); + if (error) + return error; + + if (enable) { + reg |= BQ32K_TCFE; + error = bq32k_write(dev, ®, BQ32K_CFG2, 1); + if (error) + return error; + + dev_info(dev, "Enabled trickle charge FET bypass.\n"); + } else { + reg &= ~BQ32K_TCFE; + error = bq32k_write(dev, ®, BQ32K_CFG2, 1); + if (error) + return error; + + dev_info(dev, "Disabled trickle charge FET bypass.\n"); + } + + return count; +} + +static DEVICE_ATTR(trickle_charge_bypass, 0644, + bq32k_sysfs_show_tricklecharge_bypass, + bq32k_sysfs_store_tricklecharge_bypass); + +static int bq32k_sysfs_register(struct device *dev) +{ + return device_create_file(dev, &dev_attr_trickle_charge_bypass); +} + +static void bq32k_sysfs_unregister(struct device *dev) +{ + device_remove_file(dev, &dev_attr_trickle_charge_bypass); +} + static int bq32k_probe(struct i2c_client *client, const struct i2c_device_id *id) { @@ -224,11 +284,26 @@ static int bq32k_probe(struct i2c_client *client, if (IS_ERR(rtc)) return PTR_ERR(rtc); + error = bq32k_sysfs_register(&client->dev); + if (error) { + dev_err(&client->dev, + "Unable to create sysfs entries for rtc bq32000\n"); + return error; + } + + i2c_set_clientdata(client, rtc); return 0; } +static int bq32k_remove(struct i2c_client *client) +{ + bq32k_sysfs_unregister(&client->dev); + + return 0; +} + static const struct i2c_device_id bq32k_id[] = { { "bq32000", 0 }, { } @@ -240,6 +315,7 @@ static struct i2c_driver bq32k_driver = { .name = "bq32k", }, .probe = bq32k_probe, + .remove = bq32k_remove, .id_table = bq32k_id, }; diff --git a/drivers/rtc/rtc-dm355evm.c b/drivers/rtc/rtc-dm355evm.c index 94067f8eeb10..f225cd873ff6 100644 --- a/drivers/rtc/rtc-dm355evm.c +++ b/drivers/rtc/rtc-dm355evm.c @@ -116,7 +116,7 @@ static int dm355evm_rtc_set_time(struct device *dev, struct rtc_time *tm) return 0; } -static struct rtc_class_ops dm355evm_rtc_ops = { +static const struct rtc_class_ops dm355evm_rtc_ops = { .read_time = dm355evm_rtc_read_time, .set_time = dm355evm_rtc_set_time, }; diff --git a/drivers/rtc/rtc-ds3232.c b/drivers/rtc/rtc-ds3232.c index b1f20d8c358f..9bb39a06b994 100644 --- a/drivers/rtc/rtc-ds3232.c +++ b/drivers/rtc/rtc-ds3232.c @@ -23,28 +23,28 @@ #include <linux/slab.h> #include <linux/regmap.h> -#define DS3232_REG_SECONDS 0x00 -#define DS3232_REG_MINUTES 0x01 -#define DS3232_REG_HOURS 0x02 -#define DS3232_REG_AMPM 0x02 -#define DS3232_REG_DAY 0x03 -#define DS3232_REG_DATE 0x04 -#define DS3232_REG_MONTH 0x05 -#define DS3232_REG_CENTURY 0x05 -#define DS3232_REG_YEAR 0x06 -#define DS3232_REG_ALARM1 0x07 /* Alarm 1 BASE */ -#define DS3232_REG_ALARM2 0x0B /* Alarm 2 BASE */ -#define DS3232_REG_CR 0x0E /* Control register */ -# define DS3232_REG_CR_nEOSC 0x80 -# define DS3232_REG_CR_INTCN 0x04 -# define DS3232_REG_CR_A2IE 0x02 -# define DS3232_REG_CR_A1IE 0x01 - -#define DS3232_REG_SR 0x0F /* control/status register */ -# define DS3232_REG_SR_OSF 0x80 -# define DS3232_REG_SR_BSY 0x04 -# define DS3232_REG_SR_A2F 0x02 -# define DS3232_REG_SR_A1F 0x01 +#define DS3232_REG_SECONDS 0x00 +#define DS3232_REG_MINUTES 0x01 +#define DS3232_REG_HOURS 0x02 +#define DS3232_REG_AMPM 0x02 +#define DS3232_REG_DAY 0x03 +#define DS3232_REG_DATE 0x04 +#define DS3232_REG_MONTH 0x05 +#define DS3232_REG_CENTURY 0x05 +#define DS3232_REG_YEAR 0x06 +#define DS3232_REG_ALARM1 0x07 /* Alarm 1 BASE */ +#define DS3232_REG_ALARM2 0x0B /* Alarm 2 BASE */ +#define DS3232_REG_CR 0x0E /* Control register */ +# define DS3232_REG_CR_nEOSC 0x80 +# define DS3232_REG_CR_INTCN 0x04 +# define DS3232_REG_CR_A2IE 0x02 +# define DS3232_REG_CR_A1IE 0x01 + +#define DS3232_REG_SR 0x0F /* control/status register */ +# define DS3232_REG_SR_OSF 0x80 +# define DS3232_REG_SR_BSY 0x04 +# define DS3232_REG_SR_A2F 0x02 +# define DS3232_REG_SR_A1F 0x01 struct ds3232 { struct device *dev; @@ -363,6 +363,9 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq, if (ret) return ret; + if (ds3232->irq > 0) + device_init_wakeup(dev, 1); + ds3232->rtc = devm_rtc_device_register(dev, name, &ds3232_rtc_ops, THIS_MODULE); if (IS_ERR(ds3232->rtc)) @@ -374,10 +377,10 @@ static int ds3232_probe(struct device *dev, struct regmap *regmap, int irq, IRQF_SHARED | IRQF_ONESHOT, name, dev); if (ret) { + device_set_wakeup_capable(dev, 0); ds3232->irq = 0; dev_err(dev, "unable to request IRQ\n"); - } else - device_init_wakeup(dev, 1); + } } return 0; @@ -420,6 +423,7 @@ static int ds3232_i2c_probe(struct i2c_client *client, static const struct regmap_config config = { .reg_bits = 8, .val_bits = 8, + .max_register = 0x13, }; regmap = devm_regmap_init_i2c(client, &config); @@ -479,6 +483,7 @@ static int ds3234_probe(struct spi_device *spi) static const struct regmap_config config = { .reg_bits = 8, .val_bits = 8, + .max_register = 0x13, .write_flag_mask = 0x80, }; struct regmap *regmap; diff --git a/drivers/rtc/rtc-gemini.c b/drivers/rtc/rtc-gemini.c index 688debc14348..ccf0dbadb62d 100644 --- a/drivers/rtc/rtc-gemini.c +++ b/drivers/rtc/rtc-gemini.c @@ -159,9 +159,16 @@ static int gemini_rtc_remove(struct platform_device *pdev) return 0; } +static const struct of_device_id gemini_rtc_dt_match[] = { + { .compatible = "cortina,gemini-rtc" }, + { } +}; +MODULE_DEVICE_TABLE(of, gemini_rtc_dt_match); + static struct platform_driver gemini_rtc_driver = { .driver = { .name = DRV_NAME, + .of_match_table = gemini_rtc_dt_match, }, .probe = gemini_rtc_probe, .remove = gemini_rtc_remove, diff --git a/drivers/rtc/rtc-imxdi.c b/drivers/rtc/rtc-imxdi.c index 67b56b80dc70..6b54f6c24c5f 100644 --- a/drivers/rtc/rtc-imxdi.c +++ b/drivers/rtc/rtc-imxdi.c @@ -108,7 +108,6 @@ * @pdev: pionter to platform dev * @rtc: pointer to rtc struct * @ioaddr: IO registers pointer - * @irq: dryice normal interrupt * @clk: input reference clock * @dsr: copy of the DSR register * @irq_lock: interrupt enable register (DIER) lock @@ -120,7 +119,6 @@ struct imxdi_dev { struct platform_device *pdev; struct rtc_device *rtc; void __iomem *ioaddr; - int irq; struct clk *clk; u32 dsr; spinlock_t irq_lock; @@ -668,7 +666,7 @@ static int dryice_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alarm) return 0; } -static struct rtc_class_ops dryice_rtc_ops = { +static const struct rtc_class_ops dryice_rtc_ops = { .read_time = dryice_rtc_read_time, .set_mmss = dryice_rtc_set_mmss, .alarm_irq_enable = dryice_rtc_alarm_irq_enable, @@ -677,9 +675,9 @@ static struct rtc_class_ops dryice_rtc_ops = { }; /* - * dryice "normal" interrupt handler + * interrupt handler for dryice "normal" and security violation interrupt */ -static irqreturn_t dryice_norm_irq(int irq, void *dev_id) +static irqreturn_t dryice_irq(int irq, void *dev_id) { struct imxdi_dev *imxdi = dev_id; u32 dsr, dier; @@ -765,6 +763,7 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) { struct resource *res; struct imxdi_dev *imxdi; + int norm_irq, sec_irq; int rc; imxdi = devm_kzalloc(&pdev->dev, sizeof(*imxdi), GFP_KERNEL); @@ -780,9 +779,16 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) spin_lock_init(&imxdi->irq_lock); - imxdi->irq = platform_get_irq(pdev, 0); - if (imxdi->irq < 0) - return imxdi->irq; + norm_irq = platform_get_irq(pdev, 0); + if (norm_irq < 0) + return norm_irq; + + /* the 2nd irq is the security violation irq + * make this optional, don't break the device tree ABI + */ + sec_irq = platform_get_irq(pdev, 1); + if (sec_irq <= 0) + sec_irq = IRQ_NOTCONNECTED; init_waitqueue_head(&imxdi->write_wait); @@ -808,13 +814,20 @@ static int __init dryice_rtc_probe(struct platform_device *pdev) if (rc != 0) goto err; - rc = devm_request_irq(&pdev->dev, imxdi->irq, dryice_norm_irq, - IRQF_SHARED, pdev->name, imxdi); + rc = devm_request_irq(&pdev->dev, norm_irq, dryice_irq, + IRQF_SHARED, pdev->name, imxdi); if (rc) { dev_warn(&pdev->dev, "interrupt not available.\n"); goto err; } + rc = devm_request_irq(&pdev->dev, sec_irq, dryice_irq, + IRQF_SHARED, pdev->name, imxdi); + if (rc) { + dev_warn(&pdev->dev, "security violation interrupt not available.\n"); + /* this is not an error, see above */ + } + platform_set_drvdata(pdev, imxdi); imxdi->rtc = devm_rtc_device_register(&pdev->dev, pdev->name, &dryice_rtc_ops, THIS_MODULE); diff --git a/drivers/rtc/rtc-ls1x.c b/drivers/rtc/rtc-ls1x.c index 22a9ec4f2b83..e04ca54f21e2 100644 --- a/drivers/rtc/rtc-ls1x.c +++ b/drivers/rtc/rtc-ls1x.c @@ -138,7 +138,7 @@ err: return ret; } -static struct rtc_class_ops ls1x_rtc_ops = { +static const struct rtc_class_ops ls1x_rtc_ops = { .read_time = ls1x_rtc_read_time, .set_time = ls1x_rtc_set_time, }; diff --git a/drivers/rtc/rtc-m48t86.c b/drivers/rtc/rtc-m48t86.c index 0eeb5714c00f..02af045305dd 100644 --- a/drivers/rtc/rtc-m48t86.c +++ b/drivers/rtc/rtc-m48t86.c @@ -16,62 +16,88 @@ #include <linux/module.h> #include <linux/rtc.h> #include <linux/platform_device.h> -#include <linux/platform_data/rtc-m48t86.h> #include <linux/bcd.h> +#include <linux/io.h> -#define M48T86_REG_SEC 0x00 -#define M48T86_REG_SECALRM 0x01 -#define M48T86_REG_MIN 0x02 -#define M48T86_REG_MINALRM 0x03 -#define M48T86_REG_HOUR 0x04 -#define M48T86_REG_HOURALRM 0x05 -#define M48T86_REG_DOW 0x06 /* 1 = sunday */ -#define M48T86_REG_DOM 0x07 -#define M48T86_REG_MONTH 0x08 /* 1 - 12 */ -#define M48T86_REG_YEAR 0x09 /* 0 - 99 */ -#define M48T86_REG_A 0x0A -#define M48T86_REG_B 0x0B -#define M48T86_REG_C 0x0C -#define M48T86_REG_D 0x0D - -#define M48T86_REG_B_H24 (1 << 1) -#define M48T86_REG_B_DM (1 << 2) -#define M48T86_REG_B_SET (1 << 7) -#define M48T86_REG_D_VRT (1 << 7) +#define M48T86_SEC 0x00 +#define M48T86_SECALRM 0x01 +#define M48T86_MIN 0x02 +#define M48T86_MINALRM 0x03 +#define M48T86_HOUR 0x04 +#define M48T86_HOURALRM 0x05 +#define M48T86_DOW 0x06 /* 1 = sunday */ +#define M48T86_DOM 0x07 +#define M48T86_MONTH 0x08 /* 1 - 12 */ +#define M48T86_YEAR 0x09 /* 0 - 99 */ +#define M48T86_A 0x0a +#define M48T86_B 0x0b +#define M48T86_B_SET BIT(7) +#define M48T86_B_DM BIT(2) +#define M48T86_B_H24 BIT(1) +#define M48T86_C 0x0c +#define M48T86_D 0x0d +#define M48T86_D_VRT BIT(7) +#define M48T86_NVRAM(x) (0x0e + (x)) +#define M48T86_NVRAM_LEN 114 + +struct m48t86_rtc_info { + void __iomem *index_reg; + void __iomem *data_reg; + struct rtc_device *rtc; +}; + +static unsigned char m48t86_readb(struct device *dev, unsigned long addr) +{ + struct m48t86_rtc_info *info = dev_get_drvdata(dev); + unsigned char value; + + writeb(addr, info->index_reg); + value = readb(info->data_reg); + + return value; +} + +static void m48t86_writeb(struct device *dev, + unsigned char value, unsigned long addr) +{ + struct m48t86_rtc_info *info = dev_get_drvdata(dev); + + writeb(addr, info->index_reg); + writeb(value, info->data_reg); +} static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm) { unsigned char reg; - struct platform_device *pdev = to_platform_device(dev); - struct m48t86_ops *ops = dev_get_platdata(&pdev->dev); - reg = ops->readbyte(M48T86_REG_B); + reg = m48t86_readb(dev, M48T86_B); - if (reg & M48T86_REG_B_DM) { + if (reg & M48T86_B_DM) { /* data (binary) mode */ - tm->tm_sec = ops->readbyte(M48T86_REG_SEC); - tm->tm_min = ops->readbyte(M48T86_REG_MIN); - tm->tm_hour = ops->readbyte(M48T86_REG_HOUR) & 0x3F; - tm->tm_mday = ops->readbyte(M48T86_REG_DOM); + tm->tm_sec = m48t86_readb(dev, M48T86_SEC); + tm->tm_min = m48t86_readb(dev, M48T86_MIN); + tm->tm_hour = m48t86_readb(dev, M48T86_HOUR) & 0x3f; + tm->tm_mday = m48t86_readb(dev, M48T86_DOM); /* tm_mon is 0-11 */ - tm->tm_mon = ops->readbyte(M48T86_REG_MONTH) - 1; - tm->tm_year = ops->readbyte(M48T86_REG_YEAR) + 100; - tm->tm_wday = ops->readbyte(M48T86_REG_DOW); + tm->tm_mon = m48t86_readb(dev, M48T86_MONTH) - 1; + tm->tm_year = m48t86_readb(dev, M48T86_YEAR) + 100; + tm->tm_wday = m48t86_readb(dev, M48T86_DOW); } else { /* bcd mode */ - tm->tm_sec = bcd2bin(ops->readbyte(M48T86_REG_SEC)); - tm->tm_min = bcd2bin(ops->readbyte(M48T86_REG_MIN)); - tm->tm_hour = bcd2bin(ops->readbyte(M48T86_REG_HOUR) & 0x3F); - tm->tm_mday = bcd2bin(ops->readbyte(M48T86_REG_DOM)); + tm->tm_sec = bcd2bin(m48t86_readb(dev, M48T86_SEC)); + tm->tm_min = bcd2bin(m48t86_readb(dev, M48T86_MIN)); + tm->tm_hour = bcd2bin(m48t86_readb(dev, M48T86_HOUR) & + 0x3f); + tm->tm_mday = bcd2bin(m48t86_readb(dev, M48T86_DOM)); /* tm_mon is 0-11 */ - tm->tm_mon = bcd2bin(ops->readbyte(M48T86_REG_MONTH)) - 1; - tm->tm_year = bcd2bin(ops->readbyte(M48T86_REG_YEAR)) + 100; - tm->tm_wday = bcd2bin(ops->readbyte(M48T86_REG_DOW)); + tm->tm_mon = bcd2bin(m48t86_readb(dev, M48T86_MONTH)) - 1; + tm->tm_year = bcd2bin(m48t86_readb(dev, M48T86_YEAR)) + 100; + tm->tm_wday = bcd2bin(m48t86_readb(dev, M48T86_DOW)); } /* correct the hour if the clock is in 12h mode */ - if (!(reg & M48T86_REG_B_H24)) - if (ops->readbyte(M48T86_REG_HOUR) & 0x80) + if (!(reg & M48T86_B_H24)) + if (m48t86_readb(dev, M48T86_HOUR) & 0x80) tm->tm_hour += 12; return rtc_valid_tm(tm); @@ -80,38 +106,36 @@ static int m48t86_rtc_read_time(struct device *dev, struct rtc_time *tm) static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm) { unsigned char reg; - struct platform_device *pdev = to_platform_device(dev); - struct m48t86_ops *ops = dev_get_platdata(&pdev->dev); - reg = ops->readbyte(M48T86_REG_B); + reg = m48t86_readb(dev, M48T86_B); /* update flag and 24h mode */ - reg |= M48T86_REG_B_SET | M48T86_REG_B_H24; - ops->writebyte(reg, M48T86_REG_B); + reg |= M48T86_B_SET | M48T86_B_H24; + m48t86_writeb(dev, reg, M48T86_B); - if (reg & M48T86_REG_B_DM) { + if (reg & M48T86_B_DM) { /* data (binary) mode */ - ops->writebyte(tm->tm_sec, M48T86_REG_SEC); - ops->writebyte(tm->tm_min, M48T86_REG_MIN); - ops->writebyte(tm->tm_hour, M48T86_REG_HOUR); - ops->writebyte(tm->tm_mday, M48T86_REG_DOM); - ops->writebyte(tm->tm_mon + 1, M48T86_REG_MONTH); - ops->writebyte(tm->tm_year % 100, M48T86_REG_YEAR); - ops->writebyte(tm->tm_wday, M48T86_REG_DOW); + m48t86_writeb(dev, tm->tm_sec, M48T86_SEC); + m48t86_writeb(dev, tm->tm_min, M48T86_MIN); + m48t86_writeb(dev, tm->tm_hour, M48T86_HOUR); + m48t86_writeb(dev, tm->tm_mday, M48T86_DOM); + m48t86_writeb(dev, tm->tm_mon + 1, M48T86_MONTH); + m48t86_writeb(dev, tm->tm_year % 100, M48T86_YEAR); + m48t86_writeb(dev, tm->tm_wday, M48T86_DOW); } else { /* bcd mode */ - ops->writebyte(bin2bcd(tm->tm_sec), M48T86_REG_SEC); - ops->writebyte(bin2bcd(tm->tm_min), M48T86_REG_MIN); - ops->writebyte(bin2bcd(tm->tm_hour), M48T86_REG_HOUR); - ops->writebyte(bin2bcd(tm->tm_mday), M48T86_REG_DOM); - ops->writebyte(bin2bcd(tm->tm_mon + 1), M48T86_REG_MONTH); - ops->writebyte(bin2bcd(tm->tm_year % 100), M48T86_REG_YEAR); - ops->writebyte(bin2bcd(tm->tm_wday), M48T86_REG_DOW); + m48t86_writeb(dev, bin2bcd(tm->tm_sec), M48T86_SEC); + m48t86_writeb(dev, bin2bcd(tm->tm_min), M48T86_MIN); + m48t86_writeb(dev, bin2bcd(tm->tm_hour), M48T86_HOUR); + m48t86_writeb(dev, bin2bcd(tm->tm_mday), M48T86_DOM); + m48t86_writeb(dev, bin2bcd(tm->tm_mon + 1), M48T86_MONTH); + m48t86_writeb(dev, bin2bcd(tm->tm_year % 100), M48T86_YEAR); + m48t86_writeb(dev, bin2bcd(tm->tm_wday), M48T86_DOW); } /* update ended */ - reg &= ~M48T86_REG_B_SET; - ops->writebyte(reg, M48T86_REG_B); + reg &= ~M48T86_B_SET; + m48t86_writeb(dev, reg, M48T86_B); return 0; } @@ -119,18 +143,16 @@ static int m48t86_rtc_set_time(struct device *dev, struct rtc_time *tm) static int m48t86_rtc_proc(struct device *dev, struct seq_file *seq) { unsigned char reg; - struct platform_device *pdev = to_platform_device(dev); - struct m48t86_ops *ops = dev_get_platdata(&pdev->dev); - reg = ops->readbyte(M48T86_REG_B); + reg = m48t86_readb(dev, M48T86_B); seq_printf(seq, "mode\t\t: %s\n", - (reg & M48T86_REG_B_DM) ? "binary" : "bcd"); + (reg & M48T86_B_DM) ? "binary" : "bcd"); - reg = ops->readbyte(M48T86_REG_D); + reg = m48t86_readb(dev, M48T86_D); seq_printf(seq, "battery\t\t: %s\n", - (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted"); + (reg & M48T86_D_VRT) ? "ok" : "exhausted"); return 0; } @@ -141,25 +163,116 @@ static const struct rtc_class_ops m48t86_rtc_ops = { .proc = m48t86_rtc_proc, }; -static int m48t86_rtc_probe(struct platform_device *dev) +static ssize_t m48t86_nvram_read(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) +{ + struct device *dev = kobj_to_dev(kobj); + unsigned int i; + + for (i = 0; i < count; i++) + buf[i] = m48t86_readb(dev, M48T86_NVRAM(off + i)); + + return count; +} + +static ssize_t m48t86_nvram_write(struct file *filp, struct kobject *kobj, + struct bin_attribute *attr, + char *buf, loff_t off, size_t count) { + struct device *dev = kobj_to_dev(kobj); + unsigned int i; + + for (i = 0; i < count; i++) + m48t86_writeb(dev, buf[i], M48T86_NVRAM(off + i)); + + return count; +} + +static BIN_ATTR(nvram, 0644, m48t86_nvram_read, m48t86_nvram_write, + M48T86_NVRAM_LEN); + +/* + * The RTC is an optional feature at purchase time on some Technologic Systems + * boards. Verify that it actually exists by checking if the last two bytes + * of the NVRAM can be changed. + * + * This is based on the method used in their rtc7800.c example. + */ +static bool m48t86_verify_chip(struct platform_device *pdev) +{ + unsigned int offset0 = M48T86_NVRAM(M48T86_NVRAM_LEN - 2); + unsigned int offset1 = M48T86_NVRAM(M48T86_NVRAM_LEN - 1); + unsigned char tmp0, tmp1; + + tmp0 = m48t86_readb(&pdev->dev, offset0); + tmp1 = m48t86_readb(&pdev->dev, offset1); + + m48t86_writeb(&pdev->dev, 0x00, offset0); + m48t86_writeb(&pdev->dev, 0x55, offset1); + if (m48t86_readb(&pdev->dev, offset1) == 0x55) { + m48t86_writeb(&pdev->dev, 0xaa, offset1); + if (m48t86_readb(&pdev->dev, offset1) == 0xaa && + m48t86_readb(&pdev->dev, offset0) == 0x00) { + m48t86_writeb(&pdev->dev, tmp0, offset0); + m48t86_writeb(&pdev->dev, tmp1, offset1); + + return true; + } + } + return false; +} + +static int m48t86_rtc_probe(struct platform_device *pdev) +{ + struct m48t86_rtc_info *info; + struct resource *res; unsigned char reg; - struct m48t86_ops *ops = dev_get_platdata(&dev->dev); - struct rtc_device *rtc; - rtc = devm_rtc_device_register(&dev->dev, "m48t86", - &m48t86_rtc_ops, THIS_MODULE); + info = devm_kzalloc(&pdev->dev, sizeof(*info), GFP_KERNEL); + if (!info) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return -ENODEV; + info->index_reg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(info->index_reg)) + return PTR_ERR(info->index_reg); + + res = platform_get_resource(pdev, IORESOURCE_MEM, 1); + if (!res) + return -ENODEV; + info->data_reg = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(info->data_reg)) + return PTR_ERR(info->data_reg); - if (IS_ERR(rtc)) - return PTR_ERR(rtc); + dev_set_drvdata(&pdev->dev, info); + + if (!m48t86_verify_chip(pdev)) { + dev_info(&pdev->dev, "RTC not present\n"); + return -ENODEV; + } - platform_set_drvdata(dev, rtc); + info->rtc = devm_rtc_device_register(&pdev->dev, "m48t86", + &m48t86_rtc_ops, THIS_MODULE); + if (IS_ERR(info->rtc)) + return PTR_ERR(info->rtc); /* read battery status */ - reg = ops->readbyte(M48T86_REG_D); - dev_info(&dev->dev, "battery %s\n", - (reg & M48T86_REG_D_VRT) ? "ok" : "exhausted"); + reg = m48t86_readb(&pdev->dev, M48T86_D); + dev_info(&pdev->dev, "battery %s\n", + (reg & M48T86_D_VRT) ? "ok" : "exhausted"); + if (device_create_bin_file(&pdev->dev, &bin_attr_nvram)) + dev_err(&pdev->dev, "failed to create nvram sysfs entry\n"); + + return 0; +} + +static int m48t86_rtc_remove(struct platform_device *pdev) +{ + device_remove_bin_file(&pdev->dev, &bin_attr_nvram); return 0; } @@ -168,6 +281,7 @@ static struct platform_driver m48t86_rtc_platform_driver = { .name = "rtc-m48t86", }, .probe = m48t86_rtc_probe, + .remove = m48t86_rtc_remove, }; module_platform_driver(m48t86_rtc_platform_driver); diff --git a/drivers/rtc/rtc-mcp795.c b/drivers/rtc/rtc-mcp795.c index ce75e421ba00..77f21331ae21 100644 --- a/drivers/rtc/rtc-mcp795.c +++ b/drivers/rtc/rtc-mcp795.c @@ -44,12 +44,22 @@ #define MCP795_REG_DAY 0x04 #define MCP795_REG_MONTH 0x06 #define MCP795_REG_CONTROL 0x08 +#define MCP795_REG_ALM0_SECONDS 0x0C +#define MCP795_REG_ALM0_DAY 0x0F #define MCP795_ST_BIT BIT(7) #define MCP795_24_BIT BIT(6) #define MCP795_LP_BIT BIT(5) #define MCP795_EXTOSC_BIT BIT(3) #define MCP795_OSCON_BIT BIT(5) +#define MCP795_ALM0_BIT BIT(4) +#define MCP795_ALM1_BIT BIT(5) +#define MCP795_ALM0IF_BIT BIT(3) +#define MCP795_ALM0C0_BIT BIT(4) +#define MCP795_ALM0C1_BIT BIT(5) +#define MCP795_ALM0C2_BIT BIT(6) + +#define SEC_PER_DAY (24 * 60 * 60) static int mcp795_rtcc_read(struct device *dev, u8 addr, u8 *buf, u8 count) { @@ -150,6 +160,30 @@ static int mcp795_start_oscillator(struct device *dev, bool *extosc) dev, MCP795_REG_SECONDS, MCP795_ST_BIT, MCP795_ST_BIT); } +/* Enable or disable Alarm 0 in RTC */ +static int mcp795_update_alarm(struct device *dev, bool enable) +{ + int ret; + + dev_dbg(dev, "%s alarm\n", enable ? "Enable" : "Disable"); + + if (enable) { + /* clear ALM0IF (Alarm 0 Interrupt Flag) bit */ + ret = mcp795_rtcc_set_bits(dev, MCP795_REG_ALM0_DAY, + MCP795_ALM0IF_BIT, 0); + if (ret) + return ret; + /* enable alarm 0 */ + ret = mcp795_rtcc_set_bits(dev, MCP795_REG_CONTROL, + MCP795_ALM0_BIT, MCP795_ALM0_BIT); + } else { + /* disable alarm 0 and alarm 1 */ + ret = mcp795_rtcc_set_bits(dev, MCP795_REG_CONTROL, + MCP795_ALM0_BIT | MCP795_ALM1_BIT, 0); + } + return ret; +} + static int mcp795_set_time(struct device *dev, struct rtc_time *tim) { int ret; @@ -170,6 +204,7 @@ static int mcp795_set_time(struct device *dev, struct rtc_time *tim) data[0] = (data[0] & 0x80) | bin2bcd(tim->tm_sec); data[1] = (data[1] & 0x80) | bin2bcd(tim->tm_min); data[2] = bin2bcd(tim->tm_hour); + data[3] = (data[3] & 0xF8) | bin2bcd(tim->tm_wday + 1); data[4] = bin2bcd(tim->tm_mday); data[5] = (data[5] & MCP795_LP_BIT) | bin2bcd(tim->tm_mon + 1); @@ -198,9 +233,9 @@ static int mcp795_set_time(struct device *dev, struct rtc_time *tim) if (ret) return ret; - dev_dbg(dev, "Set mcp795: %04d-%02d-%02d %02d:%02d:%02d\n", + dev_dbg(dev, "Set mcp795: %04d-%02d-%02d(%d) %02d:%02d:%02d\n", tim->tm_year + 1900, tim->tm_mon, tim->tm_mday, - tim->tm_hour, tim->tm_min, tim->tm_sec); + tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec); return 0; } @@ -218,20 +253,139 @@ static int mcp795_read_time(struct device *dev, struct rtc_time *tim) tim->tm_sec = bcd2bin(data[0] & 0x7F); tim->tm_min = bcd2bin(data[1] & 0x7F); tim->tm_hour = bcd2bin(data[2] & 0x3F); + tim->tm_wday = bcd2bin(data[3] & 0x07) - 1; tim->tm_mday = bcd2bin(data[4] & 0x3F); tim->tm_mon = bcd2bin(data[5] & 0x1F) - 1; tim->tm_year = bcd2bin(data[6]) + 100; /* Assume we are in 20xx */ - dev_dbg(dev, "Read from mcp795: %04d-%02d-%02d %02d:%02d:%02d\n", - tim->tm_year + 1900, tim->tm_mon, tim->tm_mday, - tim->tm_hour, tim->tm_min, tim->tm_sec); + dev_dbg(dev, "Read from mcp795: %04d-%02d-%02d(%d) %02d:%02d:%02d\n", + tim->tm_year + 1900, tim->tm_mon, tim->tm_mday, + tim->tm_wday, tim->tm_hour, tim->tm_min, tim->tm_sec); return rtc_valid_tm(tim); } +static int mcp795_set_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + struct rtc_time now_tm; + time64_t now; + time64_t later; + u8 tmp[6]; + int ret; + + /* Read current time from RTC hardware */ + ret = mcp795_read_time(dev, &now_tm); + if (ret) + return ret; + /* Get the number of seconds since 1970 */ + now = rtc_tm_to_time64(&now_tm); + later = rtc_tm_to_time64(&alm->time); + if (later <= now) + return -EINVAL; + /* make sure alarm fires within the next one year */ + if ((later - now) >= + (SEC_PER_DAY * (365 + is_leap_year(alm->time.tm_year)))) + return -EDOM; + /* disable alarm */ + ret = mcp795_update_alarm(dev, false); + if (ret) + return ret; + /* Read registers, so we can leave configuration bits untouched */ + ret = mcp795_rtcc_read(dev, MCP795_REG_ALM0_SECONDS, tmp, sizeof(tmp)); + if (ret) + return ret; + + alm->time.tm_year = -1; + alm->time.tm_isdst = -1; + alm->time.tm_yday = -1; + + tmp[0] = (tmp[0] & 0x80) | bin2bcd(alm->time.tm_sec); + tmp[1] = (tmp[1] & 0x80) | bin2bcd(alm->time.tm_min); + tmp[2] = (tmp[2] & 0xE0) | bin2bcd(alm->time.tm_hour); + tmp[3] = (tmp[3] & 0x80) | bin2bcd(alm->time.tm_wday + 1); + /* set alarm match: seconds, minutes, hour, day, date and month */ + tmp[3] |= (MCP795_ALM0C2_BIT | MCP795_ALM0C1_BIT | MCP795_ALM0C0_BIT); + tmp[4] = (tmp[4] & 0xC0) | bin2bcd(alm->time.tm_mday); + tmp[5] = (tmp[5] & 0xE0) | bin2bcd(alm->time.tm_mon + 1); + + ret = mcp795_rtcc_write(dev, MCP795_REG_ALM0_SECONDS, tmp, sizeof(tmp)); + if (ret) + return ret; + + /* enable alarm if requested */ + if (alm->enabled) { + ret = mcp795_update_alarm(dev, true); + if (ret) + return ret; + dev_dbg(dev, "Alarm IRQ armed\n"); + } + dev_dbg(dev, "Set alarm: %02d-%02d(%d) %02d:%02d:%02d\n", + alm->time.tm_mon, alm->time.tm_mday, alm->time.tm_wday, + alm->time.tm_hour, alm->time.tm_min, alm->time.tm_sec); + return 0; +} + +static int mcp795_read_alarm(struct device *dev, struct rtc_wkalrm *alm) +{ + u8 data[6]; + int ret; + + ret = mcp795_rtcc_read( + dev, MCP795_REG_ALM0_SECONDS, data, sizeof(data)); + if (ret) + return ret; + + alm->time.tm_sec = bcd2bin(data[0] & 0x7F); + alm->time.tm_min = bcd2bin(data[1] & 0x7F); + alm->time.tm_hour = bcd2bin(data[2] & 0x1F); + alm->time.tm_wday = bcd2bin(data[3] & 0x07) - 1; + alm->time.tm_mday = bcd2bin(data[4] & 0x3F); + alm->time.tm_mon = bcd2bin(data[5] & 0x1F) - 1; + alm->time.tm_year = -1; + alm->time.tm_isdst = -1; + alm->time.tm_yday = -1; + + dev_dbg(dev, "Read alarm: %02d-%02d(%d) %02d:%02d:%02d\n", + alm->time.tm_mon, alm->time.tm_mday, alm->time.tm_wday, + alm->time.tm_hour, alm->time.tm_min, alm->time.tm_sec); + return 0; +} + +static int mcp795_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + return mcp795_update_alarm(dev, !!enabled); +} + +static irqreturn_t mcp795_irq(int irq, void *data) +{ + struct spi_device *spi = data; + struct rtc_device *rtc = spi_get_drvdata(spi); + struct mutex *lock = &rtc->ops_lock; + int ret; + + mutex_lock(lock); + + /* Disable alarm. + * There is no need to clear ALM0IF (Alarm 0 Interrupt Flag) bit, + * because it is done every time when alarm is enabled. + */ + ret = mcp795_update_alarm(&spi->dev, false); + if (ret) + dev_err(&spi->dev, + "Failed to disable alarm in IRQ (ret=%d)\n", ret); + rtc_update_irq(rtc, 1, RTC_AF | RTC_IRQF); + + mutex_unlock(lock); + + return IRQ_HANDLED; +} + static const struct rtc_class_ops mcp795_rtc_ops = { .read_time = mcp795_read_time, - .set_time = mcp795_set_time + .set_time = mcp795_set_time, + .read_alarm = mcp795_read_alarm, + .set_alarm = mcp795_set_alarm, + .alarm_irq_enable = mcp795_alarm_irq_enable }; static int mcp795_probe(struct spi_device *spi) @@ -259,6 +413,23 @@ static int mcp795_probe(struct spi_device *spi) spi_set_drvdata(spi, rtc); + if (spi->irq > 0) { + dev_dbg(&spi->dev, "Alarm support enabled\n"); + + /* Clear any pending alarm (ALM0IF bit) before requesting + * the interrupt. + */ + mcp795_rtcc_set_bits(&spi->dev, MCP795_REG_ALM0_DAY, + MCP795_ALM0IF_BIT, 0); + ret = devm_request_threaded_irq(&spi->dev, spi->irq, NULL, + mcp795_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, + dev_name(&rtc->dev), spi); + if (ret) + dev_err(&spi->dev, "Failed to request IRQ: %d: %d\n", + spi->irq, ret); + else + device_init_wakeup(&spi->dev, true); + } return 0; } diff --git a/drivers/rtc/rtc-mxc.c b/drivers/rtc/rtc-mxc.c index 359876a88ac8..77319122642a 100644 --- a/drivers/rtc/rtc-mxc.c +++ b/drivers/rtc/rtc-mxc.c @@ -353,7 +353,7 @@ static int mxc_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) } /* RTC layer */ -static struct rtc_class_ops mxc_rtc_ops = { +static const struct rtc_class_ops mxc_rtc_ops = { .release = mxc_rtc_release, .read_time = mxc_rtc_read_time, .set_mmss64 = mxc_rtc_set_mmss, diff --git a/drivers/rtc/rtc-pcf2127.c b/drivers/rtc/rtc-pcf2127.c index 2bfdf638b673..f33447c5db85 100644 --- a/drivers/rtc/rtc-pcf2127.c +++ b/drivers/rtc/rtc-pcf2127.c @@ -52,9 +52,20 @@ static int pcf2127_rtc_read_time(struct device *dev, struct rtc_time *tm) struct pcf2127 *pcf2127 = dev_get_drvdata(dev); unsigned char buf[10]; int ret; + int i; - ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_CTRL1, buf, - sizeof(buf)); + for (i = 0; i <= PCF2127_REG_CTRL3; i++) { + ret = regmap_read(pcf2127->regmap, PCF2127_REG_CTRL1 + i, + (unsigned int *)(buf + i)); + if (ret) { + dev_err(dev, "%s: read error\n", __func__); + return ret; + } + } + + ret = regmap_bulk_read(pcf2127->regmap, PCF2127_REG_SC, + (buf + PCF2127_REG_SC), + ARRAY_SIZE(buf) - PCF2127_REG_SC); if (ret) { dev_err(dev, "%s: read error\n", __func__); return ret; diff --git a/drivers/rtc/rtc-rx8010.c b/drivers/rtc/rtc-rx8010.c index 7163b91bb773..d08da371912c 100644 --- a/drivers/rtc/rtc-rx8010.c +++ b/drivers/rtc/rtc-rx8010.c @@ -63,7 +63,6 @@ struct rx8010_data { struct i2c_client *client; struct rtc_device *rtc; u8 ctrlreg; - spinlock_t flags_lock; }; static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id) @@ -72,12 +71,12 @@ static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id) struct rx8010_data *rx8010 = i2c_get_clientdata(client); int flagreg; - spin_lock(&rx8010->flags_lock); + mutex_lock(&rx8010->rtc->ops_lock); flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG); if (flagreg <= 0) { - spin_unlock(&rx8010->flags_lock); + mutex_unlock(&rx8010->rtc->ops_lock); return IRQ_NONE; } @@ -101,7 +100,7 @@ static irqreturn_t rx8010_irq_1_handler(int irq, void *dev_id) i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg); - spin_unlock(&rx8010->flags_lock); + mutex_unlock(&rx8010->rtc->ops_lock); return IRQ_HANDLED; } @@ -143,7 +142,6 @@ static int rx8010_set_time(struct device *dev, struct rtc_time *dt) u8 date[7]; int ctrl, flagreg; int ret; - unsigned long irqflags; if ((dt->tm_year < 100) || (dt->tm_year > 199)) return -EINVAL; @@ -181,11 +179,8 @@ static int rx8010_set_time(struct device *dev, struct rtc_time *dt) if (ret < 0) return ret; - spin_lock_irqsave(&rx8010->flags_lock, irqflags); - flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG); if (flagreg < 0) { - spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); return flagreg; } @@ -193,8 +188,6 @@ static int rx8010_set_time(struct device *dev, struct rtc_time *dt) ret = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, flagreg & ~RX8010_FLAG_VLF); - spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); - return 0; } @@ -288,12 +281,9 @@ static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t) u8 alarmvals[3]; int extreg, flagreg; int err; - unsigned long irqflags; - spin_lock_irqsave(&rx8010->flags_lock, irqflags); flagreg = i2c_smbus_read_byte_data(client, RX8010_FLAG); if (flagreg < 0) { - spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); return flagreg; } @@ -302,14 +292,12 @@ static int rx8010_set_alarm(struct device *dev, struct rtc_wkalrm *t) err = i2c_smbus_write_byte_data(rx8010->client, RX8010_CTRL, rx8010->ctrlreg); if (err < 0) { - spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); return err; } } flagreg &= ~RX8010_FLAG_AF; err = i2c_smbus_write_byte_data(rx8010->client, RX8010_FLAG, flagreg); - spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); if (err < 0) return err; @@ -404,7 +392,6 @@ static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) struct rx8010_data *rx8010 = dev_get_drvdata(dev); int ret, tmp; int flagreg; - unsigned long irqflags; switch (cmd) { case RTC_VL_READ: @@ -419,16 +406,13 @@ static int rx8010_ioctl(struct device *dev, unsigned int cmd, unsigned long arg) return 0; case RTC_VL_CLR: - spin_lock_irqsave(&rx8010->flags_lock, irqflags); flagreg = i2c_smbus_read_byte_data(rx8010->client, RX8010_FLAG); if (flagreg < 0) { - spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); return flagreg; } flagreg &= ~RX8010_FLAG_VLF; ret = i2c_smbus_write_byte_data(client, RX8010_FLAG, flagreg); - spin_unlock_irqrestore(&rx8010->flags_lock, irqflags); if (ret < 0) return ret; @@ -466,8 +450,6 @@ static int rx8010_probe(struct i2c_client *client, rx8010->client = client; i2c_set_clientdata(client, rx8010); - spin_lock_init(&rx8010->flags_lock); - err = rx8010_init_client(client); if (err) return err; diff --git a/drivers/rtc/rtc-sh.c b/drivers/rtc/rtc-sh.c index 17b6235d67a5..c626e43a9cbb 100644 --- a/drivers/rtc/rtc-sh.c +++ b/drivers/rtc/rtc-sh.c @@ -535,7 +535,7 @@ static int sh_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *wkalrm) return 0; } -static struct rtc_class_ops sh_rtc_ops = { +static const struct rtc_class_ops sh_rtc_ops = { .read_time = sh_rtc_read_time, .set_time = sh_rtc_set_time, .read_alarm = sh_rtc_read_alarm, diff --git a/drivers/rtc/rtc-snvs.c b/drivers/rtc/rtc-snvs.c index 0f11c2a228e3..d51b07d620f7 100644 --- a/drivers/rtc/rtc-snvs.c +++ b/drivers/rtc/rtc-snvs.c @@ -184,6 +184,7 @@ static int snvs_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) rtc_tm_to_time(alrm_tm, &time); regmap_update_bits(data->regmap, data->offset + SNVS_LPCR, SNVS_LPCR_LPTA_EN, 0); + rtc_write_sync_lp(data); regmap_write(data->regmap, data->offset + SNVS_LPTAR, time); /* Clear alarm interrupt status bit */ diff --git a/drivers/rtc/rtc-stm32.c b/drivers/rtc/rtc-stm32.c new file mode 100644 index 000000000000..bd57eb1029e1 --- /dev/null +++ b/drivers/rtc/rtc-stm32.c @@ -0,0 +1,725 @@ +/* + * Copyright (C) Amelie Delaunay 2016 + * Author: Amelie Delaunay <amelie.delaunay@st.com> + * License terms: GNU General Public License (GPL), version 2 + */ + +#include <linux/bcd.h> +#include <linux/clk.h> +#include <linux/iopoll.h> +#include <linux/ioport.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/regmap.h> +#include <linux/rtc.h> + +#define DRIVER_NAME "stm32_rtc" + +/* STM32 RTC registers */ +#define STM32_RTC_TR 0x00 +#define STM32_RTC_DR 0x04 +#define STM32_RTC_CR 0x08 +#define STM32_RTC_ISR 0x0C +#define STM32_RTC_PRER 0x10 +#define STM32_RTC_ALRMAR 0x1C +#define STM32_RTC_WPR 0x24 + +/* STM32_RTC_TR bit fields */ +#define STM32_RTC_TR_SEC_SHIFT 0 +#define STM32_RTC_TR_SEC GENMASK(6, 0) +#define STM32_RTC_TR_MIN_SHIFT 8 +#define STM32_RTC_TR_MIN GENMASK(14, 8) +#define STM32_RTC_TR_HOUR_SHIFT 16 +#define STM32_RTC_TR_HOUR GENMASK(21, 16) + +/* STM32_RTC_DR bit fields */ +#define STM32_RTC_DR_DATE_SHIFT 0 +#define STM32_RTC_DR_DATE GENMASK(5, 0) +#define STM32_RTC_DR_MONTH_SHIFT 8 +#define STM32_RTC_DR_MONTH GENMASK(12, 8) +#define STM32_RTC_DR_WDAY_SHIFT 13 +#define STM32_RTC_DR_WDAY GENMASK(15, 13) +#define STM32_RTC_DR_YEAR_SHIFT 16 +#define STM32_RTC_DR_YEAR GENMASK(23, 16) + +/* STM32_RTC_CR bit fields */ +#define STM32_RTC_CR_FMT BIT(6) +#define STM32_RTC_CR_ALRAE BIT(8) +#define STM32_RTC_CR_ALRAIE BIT(12) + +/* STM32_RTC_ISR bit fields */ +#define STM32_RTC_ISR_ALRAWF BIT(0) +#define STM32_RTC_ISR_INITS BIT(4) +#define STM32_RTC_ISR_RSF BIT(5) +#define STM32_RTC_ISR_INITF BIT(6) +#define STM32_RTC_ISR_INIT BIT(7) +#define STM32_RTC_ISR_ALRAF BIT(8) + +/* STM32_RTC_PRER bit fields */ +#define STM32_RTC_PRER_PRED_S_SHIFT 0 +#define STM32_RTC_PRER_PRED_S GENMASK(14, 0) +#define STM32_RTC_PRER_PRED_A_SHIFT 16 +#define STM32_RTC_PRER_PRED_A GENMASK(22, 16) + +/* STM32_RTC_ALRMAR and STM32_RTC_ALRMBR bit fields */ +#define STM32_RTC_ALRMXR_SEC_SHIFT 0 +#define STM32_RTC_ALRMXR_SEC GENMASK(6, 0) +#define STM32_RTC_ALRMXR_SEC_MASK BIT(7) +#define STM32_RTC_ALRMXR_MIN_SHIFT 8 +#define STM32_RTC_ALRMXR_MIN GENMASK(14, 8) +#define STM32_RTC_ALRMXR_MIN_MASK BIT(15) +#define STM32_RTC_ALRMXR_HOUR_SHIFT 16 +#define STM32_RTC_ALRMXR_HOUR GENMASK(21, 16) +#define STM32_RTC_ALRMXR_PM BIT(22) +#define STM32_RTC_ALRMXR_HOUR_MASK BIT(23) +#define STM32_RTC_ALRMXR_DATE_SHIFT 24 +#define STM32_RTC_ALRMXR_DATE GENMASK(29, 24) +#define STM32_RTC_ALRMXR_WDSEL BIT(30) +#define STM32_RTC_ALRMXR_WDAY_SHIFT 24 +#define STM32_RTC_ALRMXR_WDAY GENMASK(27, 24) +#define STM32_RTC_ALRMXR_DATE_MASK BIT(31) + +/* STM32_RTC_WPR key constants */ +#define RTC_WPR_1ST_KEY 0xCA +#define RTC_WPR_2ND_KEY 0x53 +#define RTC_WPR_WRONG_KEY 0xFF + +/* + * RTC registers are protected against parasitic write access. + * PWR_CR_DBP bit must be set to enable write access to RTC registers. + */ +/* STM32_PWR_CR */ +#define PWR_CR 0x00 +/* STM32_PWR_CR bit field */ +#define PWR_CR_DBP BIT(8) + +struct stm32_rtc { + struct rtc_device *rtc_dev; + void __iomem *base; + struct regmap *dbp; + struct clk *ck_rtc; + int irq_alarm; +}; + +static void stm32_rtc_wpr_unlock(struct stm32_rtc *rtc) +{ + writel_relaxed(RTC_WPR_1ST_KEY, rtc->base + STM32_RTC_WPR); + writel_relaxed(RTC_WPR_2ND_KEY, rtc->base + STM32_RTC_WPR); +} + +static void stm32_rtc_wpr_lock(struct stm32_rtc *rtc) +{ + writel_relaxed(RTC_WPR_WRONG_KEY, rtc->base + STM32_RTC_WPR); +} + +static int stm32_rtc_enter_init_mode(struct stm32_rtc *rtc) +{ + unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR); + + if (!(isr & STM32_RTC_ISR_INITF)) { + isr |= STM32_RTC_ISR_INIT; + writel_relaxed(isr, rtc->base + STM32_RTC_ISR); + + /* + * It takes around 2 ck_rtc clock cycles to enter in + * initialization phase mode (and have INITF flag set). As + * slowest ck_rtc frequency may be 32kHz and highest should be + * 1MHz, we poll every 10 us with a timeout of 100ms. + */ + return readl_relaxed_poll_timeout_atomic( + rtc->base + STM32_RTC_ISR, + isr, (isr & STM32_RTC_ISR_INITF), + 10, 100000); + } + + return 0; +} + +static void stm32_rtc_exit_init_mode(struct stm32_rtc *rtc) +{ + unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR); + + isr &= ~STM32_RTC_ISR_INIT; + writel_relaxed(isr, rtc->base + STM32_RTC_ISR); +} + +static int stm32_rtc_wait_sync(struct stm32_rtc *rtc) +{ + unsigned int isr = readl_relaxed(rtc->base + STM32_RTC_ISR); + + isr &= ~STM32_RTC_ISR_RSF; + writel_relaxed(isr, rtc->base + STM32_RTC_ISR); + + /* + * Wait for RSF to be set to ensure the calendar registers are + * synchronised, it takes around 2 ck_rtc clock cycles + */ + return readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR, + isr, + (isr & STM32_RTC_ISR_RSF), + 10, 100000); +} + +static irqreturn_t stm32_rtc_alarm_irq(int irq, void *dev_id) +{ + struct stm32_rtc *rtc = (struct stm32_rtc *)dev_id; + unsigned int isr, cr; + + mutex_lock(&rtc->rtc_dev->ops_lock); + + isr = readl_relaxed(rtc->base + STM32_RTC_ISR); + cr = readl_relaxed(rtc->base + STM32_RTC_CR); + + if ((isr & STM32_RTC_ISR_ALRAF) && + (cr & STM32_RTC_CR_ALRAIE)) { + /* Alarm A flag - Alarm interrupt */ + dev_dbg(&rtc->rtc_dev->dev, "Alarm occurred\n"); + + /* Pass event to the kernel */ + rtc_update_irq(rtc->rtc_dev, 1, RTC_IRQF | RTC_AF); + + /* Clear event flag, otherwise new events won't be received */ + writel_relaxed(isr & ~STM32_RTC_ISR_ALRAF, + rtc->base + STM32_RTC_ISR); + } + + mutex_unlock(&rtc->rtc_dev->ops_lock); + + return IRQ_HANDLED; +} + +/* Convert rtc_time structure from bin to bcd format */ +static void tm2bcd(struct rtc_time *tm) +{ + tm->tm_sec = bin2bcd(tm->tm_sec); + tm->tm_min = bin2bcd(tm->tm_min); + tm->tm_hour = bin2bcd(tm->tm_hour); + + tm->tm_mday = bin2bcd(tm->tm_mday); + tm->tm_mon = bin2bcd(tm->tm_mon + 1); + tm->tm_year = bin2bcd(tm->tm_year - 100); + /* + * Number of days since Sunday + * - on kernel side, 0=Sunday...6=Saturday + * - on rtc side, 0=invalid,1=Monday...7=Sunday + */ + tm->tm_wday = (!tm->tm_wday) ? 7 : tm->tm_wday; +} + +/* Convert rtc_time structure from bcd to bin format */ +static void bcd2tm(struct rtc_time *tm) +{ + tm->tm_sec = bcd2bin(tm->tm_sec); + tm->tm_min = bcd2bin(tm->tm_min); + tm->tm_hour = bcd2bin(tm->tm_hour); + + tm->tm_mday = bcd2bin(tm->tm_mday); + tm->tm_mon = bcd2bin(tm->tm_mon) - 1; + tm->tm_year = bcd2bin(tm->tm_year) + 100; + /* + * Number of days since Sunday + * - on kernel side, 0=Sunday...6=Saturday + * - on rtc side, 0=invalid,1=Monday...7=Sunday + */ + tm->tm_wday %= 7; +} + +static int stm32_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct stm32_rtc *rtc = dev_get_drvdata(dev); + unsigned int tr, dr; + + /* Time and Date in BCD format */ + tr = readl_relaxed(rtc->base + STM32_RTC_TR); + dr = readl_relaxed(rtc->base + STM32_RTC_DR); + + tm->tm_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT; + tm->tm_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT; + tm->tm_hour = (tr & STM32_RTC_TR_HOUR) >> STM32_RTC_TR_HOUR_SHIFT; + + tm->tm_mday = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT; + tm->tm_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT; + tm->tm_year = (dr & STM32_RTC_DR_YEAR) >> STM32_RTC_DR_YEAR_SHIFT; + tm->tm_wday = (dr & STM32_RTC_DR_WDAY) >> STM32_RTC_DR_WDAY_SHIFT; + + /* We don't report tm_yday and tm_isdst */ + + bcd2tm(tm); + + return 0; +} + +static int stm32_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct stm32_rtc *rtc = dev_get_drvdata(dev); + unsigned int tr, dr; + int ret = 0; + + tm2bcd(tm); + + /* Time in BCD format */ + tr = ((tm->tm_sec << STM32_RTC_TR_SEC_SHIFT) & STM32_RTC_TR_SEC) | + ((tm->tm_min << STM32_RTC_TR_MIN_SHIFT) & STM32_RTC_TR_MIN) | + ((tm->tm_hour << STM32_RTC_TR_HOUR_SHIFT) & STM32_RTC_TR_HOUR); + + /* Date in BCD format */ + dr = ((tm->tm_mday << STM32_RTC_DR_DATE_SHIFT) & STM32_RTC_DR_DATE) | + ((tm->tm_mon << STM32_RTC_DR_MONTH_SHIFT) & STM32_RTC_DR_MONTH) | + ((tm->tm_year << STM32_RTC_DR_YEAR_SHIFT) & STM32_RTC_DR_YEAR) | + ((tm->tm_wday << STM32_RTC_DR_WDAY_SHIFT) & STM32_RTC_DR_WDAY); + + stm32_rtc_wpr_unlock(rtc); + + ret = stm32_rtc_enter_init_mode(rtc); + if (ret) { + dev_err(dev, "Can't enter in init mode. Set time aborted.\n"); + goto end; + } + + writel_relaxed(tr, rtc->base + STM32_RTC_TR); + writel_relaxed(dr, rtc->base + STM32_RTC_DR); + + stm32_rtc_exit_init_mode(rtc); + + ret = stm32_rtc_wait_sync(rtc); +end: + stm32_rtc_wpr_lock(rtc); + + return ret; +} + +static int stm32_rtc_read_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct stm32_rtc *rtc = dev_get_drvdata(dev); + struct rtc_time *tm = &alrm->time; + unsigned int alrmar, cr, isr; + + alrmar = readl_relaxed(rtc->base + STM32_RTC_ALRMAR); + cr = readl_relaxed(rtc->base + STM32_RTC_CR); + isr = readl_relaxed(rtc->base + STM32_RTC_ISR); + + if (alrmar & STM32_RTC_ALRMXR_DATE_MASK) { + /* + * Date/day doesn't matter in Alarm comparison so alarm + * triggers every day + */ + tm->tm_mday = -1; + tm->tm_wday = -1; + } else { + if (alrmar & STM32_RTC_ALRMXR_WDSEL) { + /* Alarm is set to a day of week */ + tm->tm_mday = -1; + tm->tm_wday = (alrmar & STM32_RTC_ALRMXR_WDAY) >> + STM32_RTC_ALRMXR_WDAY_SHIFT; + tm->tm_wday %= 7; + } else { + /* Alarm is set to a day of month */ + tm->tm_wday = -1; + tm->tm_mday = (alrmar & STM32_RTC_ALRMXR_DATE) >> + STM32_RTC_ALRMXR_DATE_SHIFT; + } + } + + if (alrmar & STM32_RTC_ALRMXR_HOUR_MASK) { + /* Hours don't matter in Alarm comparison */ + tm->tm_hour = -1; + } else { + tm->tm_hour = (alrmar & STM32_RTC_ALRMXR_HOUR) >> + STM32_RTC_ALRMXR_HOUR_SHIFT; + if (alrmar & STM32_RTC_ALRMXR_PM) + tm->tm_hour += 12; + } + + if (alrmar & STM32_RTC_ALRMXR_MIN_MASK) { + /* Minutes don't matter in Alarm comparison */ + tm->tm_min = -1; + } else { + tm->tm_min = (alrmar & STM32_RTC_ALRMXR_MIN) >> + STM32_RTC_ALRMXR_MIN_SHIFT; + } + + if (alrmar & STM32_RTC_ALRMXR_SEC_MASK) { + /* Seconds don't matter in Alarm comparison */ + tm->tm_sec = -1; + } else { + tm->tm_sec = (alrmar & STM32_RTC_ALRMXR_SEC) >> + STM32_RTC_ALRMXR_SEC_SHIFT; + } + + bcd2tm(tm); + + alrm->enabled = (cr & STM32_RTC_CR_ALRAE) ? 1 : 0; + alrm->pending = (isr & STM32_RTC_ISR_ALRAF) ? 1 : 0; + + return 0; +} + +static int stm32_rtc_alarm_irq_enable(struct device *dev, unsigned int enabled) +{ + struct stm32_rtc *rtc = dev_get_drvdata(dev); + unsigned int isr, cr; + + cr = readl_relaxed(rtc->base + STM32_RTC_CR); + + stm32_rtc_wpr_unlock(rtc); + + /* We expose Alarm A to the kernel */ + if (enabled) + cr |= (STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE); + else + cr &= ~(STM32_RTC_CR_ALRAIE | STM32_RTC_CR_ALRAE); + writel_relaxed(cr, rtc->base + STM32_RTC_CR); + + /* Clear event flag, otherwise new events won't be received */ + isr = readl_relaxed(rtc->base + STM32_RTC_ISR); + isr &= ~STM32_RTC_ISR_ALRAF; + writel_relaxed(isr, rtc->base + STM32_RTC_ISR); + + stm32_rtc_wpr_lock(rtc); + + return 0; +} + +static int stm32_rtc_valid_alrm(struct stm32_rtc *rtc, struct rtc_time *tm) +{ + int cur_day, cur_mon, cur_year, cur_hour, cur_min, cur_sec; + unsigned int dr = readl_relaxed(rtc->base + STM32_RTC_DR); + unsigned int tr = readl_relaxed(rtc->base + STM32_RTC_TR); + + cur_day = (dr & STM32_RTC_DR_DATE) >> STM32_RTC_DR_DATE_SHIFT; + cur_mon = (dr & STM32_RTC_DR_MONTH) >> STM32_RTC_DR_MONTH_SHIFT; + cur_year = (dr & STM32_RTC_DR_YEAR) >> STM32_RTC_DR_YEAR_SHIFT; + cur_sec = (tr & STM32_RTC_TR_SEC) >> STM32_RTC_TR_SEC_SHIFT; + cur_min = (tr & STM32_RTC_TR_MIN) >> STM32_RTC_TR_MIN_SHIFT; + cur_hour = (tr & STM32_RTC_TR_HOUR) >> STM32_RTC_TR_HOUR_SHIFT; + + /* + * Assuming current date is M-D-Y H:M:S. + * RTC alarm can't be set on a specific month and year. + * So the valid alarm range is: + * M-D-Y H:M:S < alarm <= (M+1)-D-Y H:M:S + * with a specific case for December... + */ + if ((((tm->tm_year > cur_year) && + (tm->tm_mon == 0x1) && (cur_mon == 0x12)) || + ((tm->tm_year == cur_year) && + (tm->tm_mon <= cur_mon + 1))) && + ((tm->tm_mday > cur_day) || + ((tm->tm_mday == cur_day) && + ((tm->tm_hour > cur_hour) || + ((tm->tm_hour == cur_hour) && (tm->tm_min > cur_min)) || + ((tm->tm_hour == cur_hour) && (tm->tm_min == cur_min) && + (tm->tm_sec >= cur_sec)))))) + return 0; + + return -EINVAL; +} + +static int stm32_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alrm) +{ + struct stm32_rtc *rtc = dev_get_drvdata(dev); + struct rtc_time *tm = &alrm->time; + unsigned int cr, isr, alrmar; + int ret = 0; + + tm2bcd(tm); + + /* + * RTC alarm can't be set on a specific date, unless this date is + * up to the same day of month next month. + */ + if (stm32_rtc_valid_alrm(rtc, tm) < 0) { + dev_err(dev, "Alarm can be set only on upcoming month.\n"); + return -EINVAL; + } + + alrmar = 0; + /* tm_year and tm_mon are not used because not supported by RTC */ + alrmar |= (tm->tm_mday << STM32_RTC_ALRMXR_DATE_SHIFT) & + STM32_RTC_ALRMXR_DATE; + /* 24-hour format */ + alrmar &= ~STM32_RTC_ALRMXR_PM; + alrmar |= (tm->tm_hour << STM32_RTC_ALRMXR_HOUR_SHIFT) & + STM32_RTC_ALRMXR_HOUR; + alrmar |= (tm->tm_min << STM32_RTC_ALRMXR_MIN_SHIFT) & + STM32_RTC_ALRMXR_MIN; + alrmar |= (tm->tm_sec << STM32_RTC_ALRMXR_SEC_SHIFT) & + STM32_RTC_ALRMXR_SEC; + + stm32_rtc_wpr_unlock(rtc); + + /* Disable Alarm */ + cr = readl_relaxed(rtc->base + STM32_RTC_CR); + cr &= ~STM32_RTC_CR_ALRAE; + writel_relaxed(cr, rtc->base + STM32_RTC_CR); + + /* + * Poll Alarm write flag to be sure that Alarm update is allowed: it + * takes around 2 ck_rtc clock cycles + */ + ret = readl_relaxed_poll_timeout_atomic(rtc->base + STM32_RTC_ISR, + isr, + (isr & STM32_RTC_ISR_ALRAWF), + 10, 100000); + + if (ret) { + dev_err(dev, "Alarm update not allowed\n"); + goto end; + } + + /* Write to Alarm register */ + writel_relaxed(alrmar, rtc->base + STM32_RTC_ALRMAR); + + if (alrm->enabled) + stm32_rtc_alarm_irq_enable(dev, 1); + else + stm32_rtc_alarm_irq_enable(dev, 0); + +end: + stm32_rtc_wpr_lock(rtc); + + return ret; +} + +static const struct rtc_class_ops stm32_rtc_ops = { + .read_time = stm32_rtc_read_time, + .set_time = stm32_rtc_set_time, + .read_alarm = stm32_rtc_read_alarm, + .set_alarm = stm32_rtc_set_alarm, + .alarm_irq_enable = stm32_rtc_alarm_irq_enable, +}; + +static const struct of_device_id stm32_rtc_of_match[] = { + { .compatible = "st,stm32-rtc" }, + {} +}; +MODULE_DEVICE_TABLE(of, stm32_rtc_of_match); + +static int stm32_rtc_init(struct platform_device *pdev, + struct stm32_rtc *rtc) +{ + unsigned int prer, pred_a, pred_s, pred_a_max, pred_s_max, cr; + unsigned int rate; + int ret = 0; + + rate = clk_get_rate(rtc->ck_rtc); + + /* Find prediv_a and prediv_s to obtain the 1Hz calendar clock */ + pred_a_max = STM32_RTC_PRER_PRED_A >> STM32_RTC_PRER_PRED_A_SHIFT; + pred_s_max = STM32_RTC_PRER_PRED_S >> STM32_RTC_PRER_PRED_S_SHIFT; + + for (pred_a = pred_a_max; pred_a + 1 > 0; pred_a--) { + pred_s = (rate / (pred_a + 1)) - 1; + + if (((pred_s + 1) * (pred_a + 1)) == rate) + break; + } + + /* + * Can't find a 1Hz, so give priority to RTC power consumption + * by choosing the higher possible value for prediv_a + */ + if ((pred_s > pred_s_max) || (pred_a > pred_a_max)) { + pred_a = pred_a_max; + pred_s = (rate / (pred_a + 1)) - 1; + + dev_warn(&pdev->dev, "ck_rtc is %s\n", + (rate < ((pred_a + 1) * (pred_s + 1))) ? + "fast" : "slow"); + } + + stm32_rtc_wpr_unlock(rtc); + + ret = stm32_rtc_enter_init_mode(rtc); + if (ret) { + dev_err(&pdev->dev, + "Can't enter in init mode. Prescaler config failed.\n"); + goto end; + } + + prer = (pred_s << STM32_RTC_PRER_PRED_S_SHIFT) & STM32_RTC_PRER_PRED_S; + writel_relaxed(prer, rtc->base + STM32_RTC_PRER); + prer |= (pred_a << STM32_RTC_PRER_PRED_A_SHIFT) & STM32_RTC_PRER_PRED_A; + writel_relaxed(prer, rtc->base + STM32_RTC_PRER); + + /* Force 24h time format */ + cr = readl_relaxed(rtc->base + STM32_RTC_CR); + cr &= ~STM32_RTC_CR_FMT; + writel_relaxed(cr, rtc->base + STM32_RTC_CR); + + stm32_rtc_exit_init_mode(rtc); + + ret = stm32_rtc_wait_sync(rtc); +end: + stm32_rtc_wpr_lock(rtc); + + return ret; +} + +static int stm32_rtc_probe(struct platform_device *pdev) +{ + struct stm32_rtc *rtc; + struct resource *res; + int ret; + + rtc = devm_kzalloc(&pdev->dev, sizeof(*rtc), GFP_KERNEL); + if (!rtc) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + rtc->base = devm_ioremap_resource(&pdev->dev, res); + if (IS_ERR(rtc->base)) + return PTR_ERR(rtc->base); + + rtc->dbp = syscon_regmap_lookup_by_phandle(pdev->dev.of_node, + "st,syscfg"); + if (IS_ERR(rtc->dbp)) { + dev_err(&pdev->dev, "no st,syscfg\n"); + return PTR_ERR(rtc->dbp); + } + + rtc->ck_rtc = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(rtc->ck_rtc)) { + dev_err(&pdev->dev, "no ck_rtc clock"); + return PTR_ERR(rtc->ck_rtc); + } + + ret = clk_prepare_enable(rtc->ck_rtc); + if (ret) + return ret; + + regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, PWR_CR_DBP); + + /* + * After a system reset, RTC_ISR.INITS flag can be read to check if + * the calendar has been initalized or not. INITS flag is reset by a + * power-on reset (no vbat, no power-supply). It is not reset if + * ck_rtc parent clock has changed (so RTC prescalers need to be + * changed). That's why we cannot rely on this flag to know if RTC + * init has to be done. + */ + ret = stm32_rtc_init(pdev, rtc); + if (ret) + goto err; + + rtc->irq_alarm = platform_get_irq(pdev, 0); + if (rtc->irq_alarm <= 0) { + dev_err(&pdev->dev, "no alarm irq\n"); + ret = rtc->irq_alarm; + goto err; + } + + platform_set_drvdata(pdev, rtc); + + ret = device_init_wakeup(&pdev->dev, true); + if (ret) + dev_warn(&pdev->dev, + "alarm won't be able to wake up the system"); + + rtc->rtc_dev = devm_rtc_device_register(&pdev->dev, pdev->name, + &stm32_rtc_ops, THIS_MODULE); + if (IS_ERR(rtc->rtc_dev)) { + ret = PTR_ERR(rtc->rtc_dev); + dev_err(&pdev->dev, "rtc device registration failed, err=%d\n", + ret); + goto err; + } + + /* Handle RTC alarm interrupts */ + ret = devm_request_threaded_irq(&pdev->dev, rtc->irq_alarm, NULL, + stm32_rtc_alarm_irq, + IRQF_TRIGGER_RISING | IRQF_ONESHOT, + pdev->name, rtc); + if (ret) { + dev_err(&pdev->dev, "IRQ%d (alarm interrupt) already claimed\n", + rtc->irq_alarm); + goto err; + } + + /* + * If INITS flag is reset (calendar year field set to 0x00), calendar + * must be initialized + */ + if (!(readl_relaxed(rtc->base + STM32_RTC_ISR) & STM32_RTC_ISR_INITS)) + dev_warn(&pdev->dev, "Date/Time must be initialized\n"); + + return 0; +err: + clk_disable_unprepare(rtc->ck_rtc); + + regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, 0); + + device_init_wakeup(&pdev->dev, false); + + return ret; +} + +static int stm32_rtc_remove(struct platform_device *pdev) +{ + struct stm32_rtc *rtc = platform_get_drvdata(pdev); + unsigned int cr; + + /* Disable interrupts */ + stm32_rtc_wpr_unlock(rtc); + cr = readl_relaxed(rtc->base + STM32_RTC_CR); + cr &= ~STM32_RTC_CR_ALRAIE; + writel_relaxed(cr, rtc->base + STM32_RTC_CR); + stm32_rtc_wpr_lock(rtc); + + clk_disable_unprepare(rtc->ck_rtc); + + /* Enable backup domain write protection */ + regmap_update_bits(rtc->dbp, PWR_CR, PWR_CR_DBP, 0); + + device_init_wakeup(&pdev->dev, false); + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int stm32_rtc_suspend(struct device *dev) +{ + struct stm32_rtc *rtc = dev_get_drvdata(dev); + + if (device_may_wakeup(dev)) + return enable_irq_wake(rtc->irq_alarm); + + return 0; +} + +static int stm32_rtc_resume(struct device *dev) +{ + struct stm32_rtc *rtc = dev_get_drvdata(dev); + int ret = 0; + + ret = stm32_rtc_wait_sync(rtc); + if (ret < 0) + return ret; + + if (device_may_wakeup(dev)) + return disable_irq_wake(rtc->irq_alarm); + + return ret; +} +#endif + +static SIMPLE_DEV_PM_OPS(stm32_rtc_pm_ops, + stm32_rtc_suspend, stm32_rtc_resume); + +static struct platform_driver stm32_rtc_driver = { + .probe = stm32_rtc_probe, + .remove = stm32_rtc_remove, + .driver = { + .name = DRIVER_NAME, + .pm = &stm32_rtc_pm_ops, + .of_match_table = stm32_rtc_of_match, + }, +}; + +module_platform_driver(stm32_rtc_driver); + +MODULE_ALIAS("platform:" DRIVER_NAME); +MODULE_AUTHOR("Amelie Delaunay <amelie.delaunay@st.com>"); +MODULE_DESCRIPTION("STMicroelectronics STM32 Real Time Clock driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/rtc/rtc-sun6i.c b/drivers/rtc/rtc-sun6i.c index c169a2cd4727..39cbc1238b92 100644 --- a/drivers/rtc/rtc-sun6i.c +++ b/drivers/rtc/rtc-sun6i.c @@ -20,6 +20,8 @@ * more details. */ +#include <linux/clk.h> +#include <linux/clk-provider.h> #include <linux/delay.h> #include <linux/err.h> #include <linux/fs.h> @@ -33,15 +35,20 @@ #include <linux/of_device.h> #include <linux/platform_device.h> #include <linux/rtc.h> +#include <linux/slab.h> #include <linux/types.h> /* Control register */ #define SUN6I_LOSC_CTRL 0x0000 +#define SUN6I_LOSC_CTRL_KEY (0x16aa << 16) #define SUN6I_LOSC_CTRL_ALM_DHMS_ACC BIT(9) #define SUN6I_LOSC_CTRL_RTC_HMS_ACC BIT(8) #define SUN6I_LOSC_CTRL_RTC_YMD_ACC BIT(7) +#define SUN6I_LOSC_CTRL_EXT_OSC BIT(0) #define SUN6I_LOSC_CTRL_ACC_MASK GENMASK(9, 7) +#define SUN6I_LOSC_CLK_PRESCAL 0x0008 + /* RTC */ #define SUN6I_RTC_YMD 0x0010 #define SUN6I_RTC_HMS 0x0014 @@ -114,13 +121,142 @@ struct sun6i_rtc_dev { void __iomem *base; int irq; unsigned long alarm; + + struct clk_hw hw; + struct clk_hw *int_osc; + struct clk *losc; + + spinlock_t lock; +}; + +static struct sun6i_rtc_dev *sun6i_rtc; + +static unsigned long sun6i_rtc_osc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw); + u32 val; + + val = readl(rtc->base + SUN6I_LOSC_CTRL); + if (val & SUN6I_LOSC_CTRL_EXT_OSC) + return parent_rate; + + val = readl(rtc->base + SUN6I_LOSC_CLK_PRESCAL); + val &= GENMASK(4, 0); + + return parent_rate / (val + 1); +} + +static u8 sun6i_rtc_osc_get_parent(struct clk_hw *hw) +{ + struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw); + + return readl(rtc->base + SUN6I_LOSC_CTRL) & SUN6I_LOSC_CTRL_EXT_OSC; +} + +static int sun6i_rtc_osc_set_parent(struct clk_hw *hw, u8 index) +{ + struct sun6i_rtc_dev *rtc = container_of(hw, struct sun6i_rtc_dev, hw); + unsigned long flags; + u32 val; + + if (index > 1) + return -EINVAL; + + spin_lock_irqsave(&rtc->lock, flags); + val = readl(rtc->base + SUN6I_LOSC_CTRL); + val &= ~SUN6I_LOSC_CTRL_EXT_OSC; + val |= SUN6I_LOSC_CTRL_KEY; + val |= index ? SUN6I_LOSC_CTRL_EXT_OSC : 0; + writel(val, rtc->base + SUN6I_LOSC_CTRL); + spin_unlock_irqrestore(&rtc->lock, flags); + + return 0; +} + +static const struct clk_ops sun6i_rtc_osc_ops = { + .recalc_rate = sun6i_rtc_osc_recalc_rate, + + .get_parent = sun6i_rtc_osc_get_parent, + .set_parent = sun6i_rtc_osc_set_parent, }; +static void __init sun6i_rtc_clk_init(struct device_node *node) +{ + struct clk_hw_onecell_data *clk_data; + struct sun6i_rtc_dev *rtc; + struct clk_init_data init = { + .ops = &sun6i_rtc_osc_ops, + }; + const char *parents[2]; + + rtc = kzalloc(sizeof(*rtc), GFP_KERNEL); + if (!rtc) + return; + spin_lock_init(&rtc->lock); + + clk_data = kzalloc(sizeof(*clk_data) + sizeof(*clk_data->hws), + GFP_KERNEL); + if (!clk_data) + return; + spin_lock_init(&rtc->lock); + + rtc->base = of_io_request_and_map(node, 0, of_node_full_name(node)); + if (IS_ERR(rtc->base)) { + pr_crit("Can't map RTC registers"); + return; + } + + /* Switch to the external, more precise, oscillator */ + writel(SUN6I_LOSC_CTRL_KEY | SUN6I_LOSC_CTRL_EXT_OSC, + rtc->base + SUN6I_LOSC_CTRL); + + /* Yes, I know, this is ugly. */ + sun6i_rtc = rtc; + + /* Deal with old DTs */ + if (!of_get_property(node, "clocks", NULL)) + return; + + rtc->int_osc = clk_hw_register_fixed_rate_with_accuracy(NULL, + "rtc-int-osc", + NULL, 0, + 667000, + 300000000); + if (IS_ERR(rtc->int_osc)) { + pr_crit("Couldn't register the internal oscillator\n"); + return; + } + + parents[0] = clk_hw_get_name(rtc->int_osc); + parents[1] = of_clk_get_parent_name(node, 0); + + rtc->hw.init = &init; + + init.parent_names = parents; + init.num_parents = of_clk_get_parent_count(node) + 1; + of_property_read_string(node, "clock-output-names", &init.name); + + rtc->losc = clk_register(NULL, &rtc->hw); + if (IS_ERR(rtc->losc)) { + pr_crit("Couldn't register the LOSC clock\n"); + return; + } + + clk_data->num = 1; + clk_data->hws[0] = &rtc->hw; + of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data); +} +CLK_OF_DECLARE_DRIVER(sun6i_rtc_clk, "allwinner,sun6i-a31-rtc", + sun6i_rtc_clk_init); + static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id) { struct sun6i_rtc_dev *chip = (struct sun6i_rtc_dev *) id; + irqreturn_t ret = IRQ_NONE; u32 val; + spin_lock(&chip->lock); val = readl(chip->base + SUN6I_ALRM_IRQ_STA); if (val & SUN6I_ALRM_IRQ_STA_CNT_IRQ_PEND) { @@ -129,10 +265,11 @@ static irqreturn_t sun6i_rtc_alarmirq(int irq, void *id) rtc_update_irq(chip->rtc, 1, RTC_AF | RTC_IRQF); - return IRQ_HANDLED; + ret = IRQ_HANDLED; } + spin_unlock(&chip->lock); - return IRQ_NONE; + return ret; } static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip) @@ -140,6 +277,7 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip) u32 alrm_val = 0; u32 alrm_irq_val = 0; u32 alrm_wake_val = 0; + unsigned long flags; if (to) { alrm_val = SUN6I_ALRM_EN_CNT_EN; @@ -150,9 +288,11 @@ static void sun6i_rtc_setaie(int to, struct sun6i_rtc_dev *chip) chip->base + SUN6I_ALRM_IRQ_STA); } + spin_lock_irqsave(&chip->lock, flags); writel(alrm_val, chip->base + SUN6I_ALRM_EN); writel(alrm_irq_val, chip->base + SUN6I_ALRM_IRQ_EN); writel(alrm_wake_val, chip->base + SUN6I_ALARM_CONFIG); + spin_unlock_irqrestore(&chip->lock, flags); } static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) @@ -191,11 +331,15 @@ static int sun6i_rtc_gettime(struct device *dev, struct rtc_time *rtc_tm) static int sun6i_rtc_getalarm(struct device *dev, struct rtc_wkalrm *wkalrm) { struct sun6i_rtc_dev *chip = dev_get_drvdata(dev); + unsigned long flags; u32 alrm_st; u32 alrm_en; + spin_lock_irqsave(&chip->lock, flags); alrm_en = readl(chip->base + SUN6I_ALRM_IRQ_EN); alrm_st = readl(chip->base + SUN6I_ALRM_IRQ_STA); + spin_unlock_irqrestore(&chip->lock, flags); + wkalrm->enabled = !!(alrm_en & SUN6I_ALRM_EN_CNT_EN); wkalrm->pending = !!(alrm_st & SUN6I_ALRM_EN_CNT_EN); rtc_time_to_tm(chip->alarm, &wkalrm->time); @@ -349,22 +493,15 @@ static const struct rtc_class_ops sun6i_rtc_ops = { static int sun6i_rtc_probe(struct platform_device *pdev) { - struct sun6i_rtc_dev *chip; - struct resource *res; + struct sun6i_rtc_dev *chip = sun6i_rtc; int ret; - chip = devm_kzalloc(&pdev->dev, sizeof(*chip), GFP_KERNEL); if (!chip) - return -ENOMEM; + return -ENODEV; platform_set_drvdata(pdev, chip); chip->dev = &pdev->dev; - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - chip->base = devm_ioremap_resource(&pdev->dev, res); - if (IS_ERR(chip->base)) - return PTR_ERR(chip->base); - chip->irq = platform_get_irq(pdev, 0); if (chip->irq < 0) { dev_err(&pdev->dev, "No IRQ resource\n"); @@ -404,8 +541,10 @@ static int sun6i_rtc_probe(struct platform_device *pdev) /* disable alarm wakeup */ writel(0, chip->base + SUN6I_ALARM_CONFIG); - chip->rtc = rtc_device_register("rtc-sun6i", &pdev->dev, - &sun6i_rtc_ops, THIS_MODULE); + clk_prepare_enable(chip->losc); + + chip->rtc = devm_rtc_device_register(&pdev->dev, "rtc-sun6i", + &sun6i_rtc_ops, THIS_MODULE); if (IS_ERR(chip->rtc)) { dev_err(&pdev->dev, "unable to register device\n"); return PTR_ERR(chip->rtc); @@ -416,15 +555,6 @@ static int sun6i_rtc_probe(struct platform_device *pdev) return 0; } -static int sun6i_rtc_remove(struct platform_device *pdev) -{ - struct sun6i_rtc_dev *chip = platform_get_drvdata(pdev); - - rtc_device_unregister(chip->rtc); - - return 0; -} - static const struct of_device_id sun6i_rtc_dt_ids[] = { { .compatible = "allwinner,sun6i-a31-rtc" }, { /* sentinel */ }, @@ -433,15 +563,9 @@ MODULE_DEVICE_TABLE(of, sun6i_rtc_dt_ids); static struct platform_driver sun6i_rtc_driver = { .probe = sun6i_rtc_probe, - .remove = sun6i_rtc_remove, .driver = { .name = "sun6i-rtc", .of_match_table = sun6i_rtc_dt_ids, }, }; - -module_platform_driver(sun6i_rtc_driver); - -MODULE_DESCRIPTION("sun6i RTC driver"); -MODULE_AUTHOR("Chen-Yu Tsai <wens@csie.org>"); -MODULE_LICENSE("GPL"); +builtin_platform_driver(sun6i_rtc_driver); diff --git a/drivers/rtc/rtc-tegra.c b/drivers/rtc/rtc-tegra.c index 3853ba963bb5..d30d57b048d3 100644 --- a/drivers/rtc/rtc-tegra.c +++ b/drivers/rtc/rtc-tegra.c @@ -17,16 +17,18 @@ * with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -#include <linux/kernel.h> + +#include <linux/clk.h> +#include <linux/delay.h> #include <linux/init.h> -#include <linux/module.h> -#include <linux/slab.h> -#include <linux/irq.h> #include <linux/io.h> -#include <linux/delay.h> -#include <linux/rtc.h> +#include <linux/irq.h> +#include <linux/kernel.h> +#include <linux/module.h> #include <linux/platform_device.h> #include <linux/pm.h> +#include <linux/rtc.h> +#include <linux/slab.h> /* set to 1 = busy every eight 32kHz clocks during copy of sec+msec to AHB */ #define TEGRA_RTC_REG_BUSY 0x004 @@ -59,6 +61,7 @@ struct tegra_rtc_info { struct platform_device *pdev; struct rtc_device *rtc_dev; void __iomem *rtc_base; /* NULL if not initialized. */ + struct clk *clk; int tegra_rtc_irq; /* alarm and periodic irq */ spinlock_t tegra_rtc_lock; }; @@ -326,6 +329,14 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) if (info->tegra_rtc_irq <= 0) return -EBUSY; + info->clk = devm_clk_get(&pdev->dev, NULL); + if (IS_ERR(info->clk)) + return PTR_ERR(info->clk); + + ret = clk_prepare_enable(info->clk); + if (ret < 0) + return ret; + /* set context info. */ info->pdev = pdev; spin_lock_init(&info->tegra_rtc_lock); @@ -346,7 +357,7 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) ret = PTR_ERR(info->rtc_dev); dev_err(&pdev->dev, "Unable to register device (err=%d).\n", ret); - return ret; + goto disable_clk; } ret = devm_request_irq(&pdev->dev, info->tegra_rtc_irq, @@ -356,12 +367,25 @@ static int __init tegra_rtc_probe(struct platform_device *pdev) dev_err(&pdev->dev, "Unable to request interrupt for device (err=%d).\n", ret); - return ret; + goto disable_clk; } dev_notice(&pdev->dev, "Tegra internal Real Time Clock\n"); return 0; + +disable_clk: + clk_disable_unprepare(info->clk); + return ret; +} + +static int tegra_rtc_remove(struct platform_device *pdev) +{ + struct tegra_rtc_info *info = platform_get_drvdata(pdev); + + clk_disable_unprepare(info->clk); + + return 0; } #ifdef CONFIG_PM_SLEEP @@ -413,6 +437,7 @@ static void tegra_rtc_shutdown(struct platform_device *pdev) MODULE_ALIAS("platform:tegra_rtc"); static struct platform_driver tegra_rtc_driver = { + .remove = tegra_rtc_remove, .shutdown = tegra_rtc_shutdown, .driver = { .name = "tegra_rtc", diff --git a/drivers/rtc/rtc-tps65910.c b/drivers/rtc/rtc-tps65910.c index 5a3d53caa485..d0244d7979fc 100644 --- a/drivers/rtc/rtc-tps65910.c +++ b/drivers/rtc/rtc-tps65910.c @@ -21,6 +21,7 @@ #include <linux/types.h> #include <linux/rtc.h> #include <linux/bcd.h> +#include <linux/math64.h> #include <linux/platform_device.h> #include <linux/interrupt.h> #include <linux/mfd/tps65910.h> @@ -33,7 +34,21 @@ struct tps65910_rtc { /* Total number of RTC registers needed to set time*/ #define NUM_TIME_REGS (TPS65910_YEARS - TPS65910_SECONDS + 1) -static int tps65910_rtc_alarm_irq_enable(struct device *dev, unsigned enabled) +/* Total number of RTC registers needed to set compensation registers */ +#define NUM_COMP_REGS (TPS65910_RTC_COMP_MSB - TPS65910_RTC_COMP_LSB + 1) + +/* Min and max values supported with 'offset' interface (swapped sign) */ +#define MIN_OFFSET (-277761) +#define MAX_OFFSET (277778) + +/* Number of ticks per hour */ +#define TICKS_PER_HOUR (32768 * 3600) + +/* Multiplier for ppb conversions */ +#define PPB_MULT (1000000000LL) + +static int tps65910_rtc_alarm_irq_enable(struct device *dev, + unsigned int enabled) { struct tps65910 *tps = dev_get_drvdata(dev->parent); u8 val = 0; @@ -187,6 +202,133 @@ static int tps65910_rtc_set_alarm(struct device *dev, struct rtc_wkalrm *alm) return ret; } +static int tps65910_rtc_set_calibration(struct device *dev, int calibration) +{ + unsigned char comp_data[NUM_COMP_REGS]; + struct tps65910 *tps = dev_get_drvdata(dev->parent); + s16 value; + int ret; + + /* + * TPS65910 uses two's complement 16 bit value for compensation for RTC + * crystal inaccuracies. One time every hour when seconds counter + * increments from 0 to 1 compensation value will be added to internal + * RTC counter value. + * + * Compensation value 0x7FFF is prohibited value. + * + * Valid range for compensation value: [-32768 .. 32766] + */ + if ((calibration < -32768) || (calibration > 32766)) { + dev_err(dev, "RTC calibration value out of range: %d\n", + calibration); + return -EINVAL; + } + + value = (s16)calibration; + + comp_data[0] = (u16)value & 0xFF; + comp_data[1] = ((u16)value >> 8) & 0xFF; + + /* Update all the compensation registers in one shot */ + ret = regmap_bulk_write(tps->regmap, TPS65910_RTC_COMP_LSB, + comp_data, NUM_COMP_REGS); + if (ret < 0) { + dev_err(dev, "rtc_set_calibration error: %d\n", ret); + return ret; + } + + /* Enable automatic compensation */ + ret = regmap_update_bits(tps->regmap, TPS65910_RTC_CTRL, + TPS65910_RTC_CTRL_AUTO_COMP, TPS65910_RTC_CTRL_AUTO_COMP); + if (ret < 0) + dev_err(dev, "auto_comp enable failed with error: %d\n", ret); + + return ret; +} + +static int tps65910_rtc_get_calibration(struct device *dev, int *calibration) +{ + unsigned char comp_data[NUM_COMP_REGS]; + struct tps65910 *tps = dev_get_drvdata(dev->parent); + unsigned int ctrl; + u16 value; + int ret; + + ret = regmap_read(tps->regmap, TPS65910_RTC_CTRL, &ctrl); + if (ret < 0) + return ret; + + /* If automatic compensation is not enabled report back zero */ + if (!(ctrl & TPS65910_RTC_CTRL_AUTO_COMP)) { + *calibration = 0; + return 0; + } + + ret = regmap_bulk_read(tps->regmap, TPS65910_RTC_COMP_LSB, comp_data, + NUM_COMP_REGS); + if (ret < 0) { + dev_err(dev, "rtc_get_calibration error: %d\n", ret); + return ret; + } + + value = (u16)comp_data[0] | ((u16)comp_data[1] << 8); + + *calibration = (s16)value; + + return 0; +} + +static int tps65910_read_offset(struct device *dev, long *offset) +{ + int calibration; + s64 tmp; + int ret; + + ret = tps65910_rtc_get_calibration(dev, &calibration); + if (ret < 0) + return ret; + + /* Convert from RTC calibration register format to ppb format */ + tmp = calibration * (s64)PPB_MULT; + if (tmp < 0) + tmp -= TICKS_PER_HOUR / 2LL; + else + tmp += TICKS_PER_HOUR / 2LL; + tmp = div_s64(tmp, TICKS_PER_HOUR); + + /* Offset value operates in negative way, so swap sign */ + *offset = (long)-tmp; + + return 0; +} + +static int tps65910_set_offset(struct device *dev, long offset) +{ + int calibration; + s64 tmp; + int ret; + + /* Make sure offset value is within supported range */ + if (offset < MIN_OFFSET || offset > MAX_OFFSET) + return -ERANGE; + + /* Convert from ppb format to RTC calibration register format */ + tmp = offset * (s64)TICKS_PER_HOUR; + if (tmp < 0) + tmp -= PPB_MULT / 2LL; + else + tmp += PPB_MULT / 2LL; + tmp = div_s64(tmp, PPB_MULT); + + /* Offset value operates in negative way, so swap sign */ + calibration = (int)-tmp; + + ret = tps65910_rtc_set_calibration(dev, calibration); + + return ret; +} + static irqreturn_t tps65910_rtc_interrupt(int irq, void *rtc) { struct device *dev = rtc; @@ -219,6 +361,8 @@ static const struct rtc_class_ops tps65910_rtc_ops = { .read_alarm = tps65910_rtc_read_alarm, .set_alarm = tps65910_rtc_set_alarm, .alarm_irq_enable = tps65910_rtc_alarm_irq_enable, + .read_offset = tps65910_read_offset, + .set_offset = tps65910_set_offset, }; static int tps65910_rtc_probe(struct platform_device *pdev) diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c index 0f1713727d4c..0b38217f8147 100644 --- a/drivers/s390/block/dasd_eckd.c +++ b/drivers/s390/block/dasd_eckd.c @@ -4864,7 +4864,7 @@ static void dasd_eckd_dump_sense_tcw(struct dasd_device *device, break; case 3: /* tsa_intrg */ len += sprintf(page + len, PRINTK_HEADER - " tsb->tsa.intrg.: not supportet yet\n"); + " tsb->tsa.intrg.: not supported yet\n"); break; } diff --git a/drivers/s390/cio/ioasm.c b/drivers/s390/cio/ioasm.c index 8225da619014..4182f60124da 100644 --- a/drivers/s390/cio/ioasm.c +++ b/drivers/s390/cio/ioasm.c @@ -165,13 +165,15 @@ int tpi(struct tpi_info *addr) int chsc(void *chsc_area) { typedef struct { char _[4096]; } addr_type; - int cc; + int cc = -EIO; asm volatile( " .insn rre,0xb25f0000,%2,0\n" - " ipm %0\n" + "0: ipm %0\n" " srl %0,28\n" - : "=d" (cc), "=m" (*(addr_type *) chsc_area) + "1:\n" + EX_TABLE(0b, 1b) + : "+d" (cc), "=m" (*(addr_type *) chsc_area) : "d" (chsc_area), "m" (*(addr_type *) chsc_area) : "cc"); trace_s390_cio_chsc(chsc_area, cc); diff --git a/drivers/s390/crypto/Makefile b/drivers/s390/crypto/Makefile index 0a7fb83f35e5..be36f1010d75 100644 --- a/drivers/s390/crypto/Makefile +++ b/drivers/s390/crypto/Makefile @@ -10,3 +10,7 @@ zcrypt-objs += zcrypt_msgtype6.o zcrypt_msgtype50.o obj-$(CONFIG_ZCRYPT) += zcrypt.o # adapter drivers depend on ap.o and zcrypt.o obj-$(CONFIG_ZCRYPT) += zcrypt_pcixcc.o zcrypt_cex2a.o zcrypt_cex4.o + +# pkey kernel module +pkey-objs := pkey_api.o +obj-$(CONFIG_PKEY) += pkey.o diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c index 56db76c05775..9be4596d8a08 100644 --- a/drivers/s390/crypto/ap_bus.c +++ b/drivers/s390/crypto/ap_bus.c @@ -1107,16 +1107,6 @@ static void ap_config_timeout(unsigned long ptr) queue_work(system_long_wq, &ap_scan_work); } -static void ap_reset_domain(void) -{ - int i; - - if (ap_domain_index == -1 || !ap_test_config_domain(ap_domain_index)) - return; - for (i = 0; i < AP_DEVICES; i++) - ap_rapq(AP_MKQID(i, ap_domain_index)); -} - static void ap_reset_all(void) { int i, j; diff --git a/drivers/s390/crypto/ap_card.c b/drivers/s390/crypto/ap_card.c index 1cd9128593e4..cfa161ccc74e 100644 --- a/drivers/s390/crypto/ap_card.c +++ b/drivers/s390/crypto/ap_card.c @@ -58,9 +58,9 @@ static ssize_t ap_functions_show(struct device *dev, static DEVICE_ATTR(ap_functions, 0444, ap_functions_show, NULL); -static ssize_t ap_request_count_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t ap_req_count_show(struct device *dev, + struct device_attribute *attr, + char *buf) { struct ap_card *ac = to_ap_card(dev); unsigned int req_cnt; @@ -72,7 +72,23 @@ static ssize_t ap_request_count_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); } -static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL); +static ssize_t ap_req_count_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ap_card *ac = to_ap_card(dev); + struct ap_queue *aq; + + spin_lock_bh(&ap_list_lock); + for_each_ap_queue(aq, ac) + aq->total_request_count = 0; + spin_unlock_bh(&ap_list_lock); + atomic_set(&ac->total_request_count, 0); + + return count; +} + +static DEVICE_ATTR(request_count, 0644, ap_req_count_show, ap_req_count_store); static ssize_t ap_requestq_count_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/s390/crypto/ap_queue.c b/drivers/s390/crypto/ap_queue.c index 7be67fa9f224..480c58a63769 100644 --- a/drivers/s390/crypto/ap_queue.c +++ b/drivers/s390/crypto/ap_queue.c @@ -459,9 +459,9 @@ EXPORT_SYMBOL(ap_queue_resume); /* * AP queue related attributes. */ -static ssize_t ap_request_count_show(struct device *dev, - struct device_attribute *attr, - char *buf) +static ssize_t ap_req_count_show(struct device *dev, + struct device_attribute *attr, + char *buf) { struct ap_queue *aq = to_ap_queue(dev); unsigned int req_cnt; @@ -472,7 +472,20 @@ static ssize_t ap_request_count_show(struct device *dev, return snprintf(buf, PAGE_SIZE, "%d\n", req_cnt); } -static DEVICE_ATTR(request_count, 0444, ap_request_count_show, NULL); +static ssize_t ap_req_count_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct ap_queue *aq = to_ap_queue(dev); + + spin_lock_bh(&aq->lock); + aq->total_request_count = 0; + spin_unlock_bh(&aq->lock); + + return count; +} + +static DEVICE_ATTR(request_count, 0644, ap_req_count_show, ap_req_count_store); static ssize_t ap_requestq_count_show(struct device *dev, struct device_attribute *attr, char *buf) diff --git a/drivers/s390/crypto/pkey_api.c b/drivers/s390/crypto/pkey_api.c new file mode 100644 index 000000000000..40f1136f5568 --- /dev/null +++ b/drivers/s390/crypto/pkey_api.c @@ -0,0 +1,1148 @@ +/* + * pkey device driver + * + * Copyright IBM Corp. 2017 + * Author(s): Harald Freudenberger + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License (version 2 only) + * as published by the Free Software Foundation. + * + */ + +#define KMSG_COMPONENT "pkey" +#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt + +#include <linux/fs.h> +#include <linux/init.h> +#include <linux/miscdevice.h> +#include <linux/module.h> +#include <linux/slab.h> +#include <linux/kallsyms.h> +#include <linux/debugfs.h> +#include <asm/zcrypt.h> +#include <asm/cpacf.h> +#include <asm/pkey.h> + +#include "zcrypt_api.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("IBM Corporation"); +MODULE_DESCRIPTION("s390 protected key interface"); + +/* Size of parameter block used for all cca requests/replies */ +#define PARMBSIZE 512 + +/* Size of vardata block used for some of the cca requests/replies */ +#define VARDATASIZE 4096 + +/* + * debug feature data and functions + */ + +static debug_info_t *debug_info; + +#define DEBUG_DBG(...) debug_sprintf_event(debug_info, 6, ##__VA_ARGS__) +#define DEBUG_INFO(...) debug_sprintf_event(debug_info, 5, ##__VA_ARGS__) +#define DEBUG_WARN(...) debug_sprintf_event(debug_info, 4, ##__VA_ARGS__) +#define DEBUG_ERR(...) debug_sprintf_event(debug_info, 3, ##__VA_ARGS__) + +static void __init pkey_debug_init(void) +{ + debug_info = debug_register("pkey", 1, 1, 4 * sizeof(long)); + debug_register_view(debug_info, &debug_sprintf_view); + debug_set_level(debug_info, 3); +} + +static void __exit pkey_debug_exit(void) +{ + debug_unregister(debug_info); +} + +/* inside view of a secure key token (only type 0x01 version 0x04) */ +struct secaeskeytoken { + u8 type; /* 0x01 for internal key token */ + u8 res0[3]; + u8 version; /* should be 0x04 */ + u8 res1[1]; + u8 flag; /* key flags */ + u8 res2[1]; + u64 mkvp; /* master key verification pattern */ + u8 key[32]; /* key value (encrypted) */ + u8 cv[8]; /* control vector */ + u16 bitsize; /* key bit size */ + u16 keysize; /* key byte size */ + u8 tvv[4]; /* token validation value */ +} __packed; + +/* + * Simple check if the token is a valid CCA secure AES key + * token. If keybitsize is given, the bitsize of the key is + * also checked. Returns 0 on success or errno value on failure. + */ +static int check_secaeskeytoken(u8 *token, int keybitsize) +{ + struct secaeskeytoken *t = (struct secaeskeytoken *) token; + + if (t->type != 0x01) { + DEBUG_ERR( + "check_secaeskeytoken secure token check failed, type mismatch 0x%02x != 0x01\n", + (int) t->type); + return -EINVAL; + } + if (t->version != 0x04) { + DEBUG_ERR( + "check_secaeskeytoken secure token check failed, version mismatch 0x%02x != 0x04\n", + (int) t->version); + return -EINVAL; + } + if (keybitsize > 0 && t->bitsize != keybitsize) { + DEBUG_ERR( + "check_secaeskeytoken secure token check failed, bitsize mismatch %d != %d\n", + (int) t->bitsize, keybitsize); + return -EINVAL; + } + + return 0; +} + +/* + * Allocate consecutive memory for request CPRB, request param + * block, reply CPRB and reply param block and fill in values + * for the common fields. Returns 0 on success or errno value + * on failure. + */ +static int alloc_and_prep_cprbmem(size_t paramblen, + u8 **pcprbmem, + struct CPRBX **preqCPRB, + struct CPRBX **prepCPRB) +{ + u8 *cprbmem; + size_t cprbplusparamblen = sizeof(struct CPRBX) + paramblen; + struct CPRBX *preqcblk, *prepcblk; + + /* + * allocate consecutive memory for request CPRB, request param + * block, reply CPRB and reply param block + */ + cprbmem = kmalloc(2 * cprbplusparamblen, GFP_KERNEL); + if (!cprbmem) + return -ENOMEM; + memset(cprbmem, 0, 2 * cprbplusparamblen); + + preqcblk = (struct CPRBX *) cprbmem; + prepcblk = (struct CPRBX *) (cprbmem + cprbplusparamblen); + + /* fill request cprb struct */ + preqcblk->cprb_len = sizeof(struct CPRBX); + preqcblk->cprb_ver_id = 0x02; + memcpy(preqcblk->func_id, "T2", 2); + preqcblk->rpl_msgbl = cprbplusparamblen; + if (paramblen) { + preqcblk->req_parmb = + ((u8 *) preqcblk) + sizeof(struct CPRBX); + preqcblk->rpl_parmb = + ((u8 *) prepcblk) + sizeof(struct CPRBX); + } + + *pcprbmem = cprbmem; + *preqCPRB = preqcblk; + *prepCPRB = prepcblk; + + return 0; +} + +/* + * Free the cprb memory allocated with the function above. + * If the scrub value is not zero, the memory is filled + * with zeros before freeing (useful if there was some + * clear key material in there). + */ +static void free_cprbmem(void *mem, size_t paramblen, int scrub) +{ + if (scrub) + memzero_explicit(mem, 2 * (sizeof(struct CPRBX) + paramblen)); + kfree(mem); +} + +/* + * Helper function to prepare the xcrb struct + */ +static inline void prep_xcrb(struct ica_xcRB *pxcrb, + u16 cardnr, + struct CPRBX *preqcblk, + struct CPRBX *prepcblk) +{ + memset(pxcrb, 0, sizeof(*pxcrb)); + pxcrb->agent_ID = 0x4341; /* 'CA' */ + pxcrb->user_defined = (cardnr == 0xFFFF ? AUTOSELECT : cardnr); + pxcrb->request_control_blk_length = + preqcblk->cprb_len + preqcblk->req_parml; + pxcrb->request_control_blk_addr = (void *) preqcblk; + pxcrb->reply_control_blk_length = preqcblk->rpl_msgbl; + pxcrb->reply_control_blk_addr = (void *) prepcblk; +} + +/* + * Helper function which calls zcrypt_send_cprb with + * memory management segment adjusted to kernel space + * so that the copy_from_user called within this + * function do in fact copy from kernel space. + */ +static inline int _zcrypt_send_cprb(struct ica_xcRB *xcrb) +{ + int rc; + mm_segment_t old_fs = get_fs(); + + set_fs(KERNEL_DS); + rc = zcrypt_send_cprb(xcrb); + set_fs(old_fs); + + return rc; +} + +/* + * Generate (random) AES secure key. + */ +int pkey_genseckey(u16 cardnr, u16 domain, + u32 keytype, struct pkey_seckey *seckey) +{ + int i, rc, keysize; + int seckeysize; + u8 *mem; + struct CPRBX *preqcblk, *prepcblk; + struct ica_xcRB xcrb; + struct kgreqparm { + u8 subfunc_code[2]; + u16 rule_array_len; + struct lv1 { + u16 len; + char key_form[8]; + char key_length[8]; + char key_type1[8]; + char key_type2[8]; + } lv1; + struct lv2 { + u16 len; + struct keyid { + u16 len; + u16 attr; + u8 data[SECKEYBLOBSIZE]; + } keyid[6]; + } lv2; + } *preqparm; + struct kgrepparm { + u8 subfunc_code[2]; + u16 rule_array_len; + struct lv3 { + u16 len; + u16 keyblocklen; + struct { + u16 toklen; + u16 tokattr; + u8 tok[0]; + /* ... some more data ... */ + } keyblock; + } lv3; + } *prepparm; + + /* get already prepared memory for 2 cprbs with param block each */ + rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); + if (rc) + return rc; + + /* fill request cprb struct */ + preqcblk->domain = domain; + + /* fill request cprb param block with KG request */ + preqparm = (struct kgreqparm *) preqcblk->req_parmb; + memcpy(preqparm->subfunc_code, "KG", 2); + preqparm->rule_array_len = sizeof(preqparm->rule_array_len); + preqparm->lv1.len = sizeof(struct lv1); + memcpy(preqparm->lv1.key_form, "OP ", 8); + switch (keytype) { + case PKEY_KEYTYPE_AES_128: + keysize = 16; + memcpy(preqparm->lv1.key_length, "KEYLN16 ", 8); + break; + case PKEY_KEYTYPE_AES_192: + keysize = 24; + memcpy(preqparm->lv1.key_length, "KEYLN24 ", 8); + break; + case PKEY_KEYTYPE_AES_256: + keysize = 32; + memcpy(preqparm->lv1.key_length, "KEYLN32 ", 8); + break; + default: + DEBUG_ERR( + "pkey_genseckey unknown/unsupported keytype %d\n", + keytype); + rc = -EINVAL; + goto out; + } + memcpy(preqparm->lv1.key_type1, "AESDATA ", 8); + preqparm->lv2.len = sizeof(struct lv2); + for (i = 0; i < 6; i++) { + preqparm->lv2.keyid[i].len = sizeof(struct keyid); + preqparm->lv2.keyid[i].attr = (i == 2 ? 0x30 : 0x10); + } + preqcblk->req_parml = sizeof(struct kgreqparm); + + /* fill xcrb struct */ + prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); + + /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ + rc = _zcrypt_send_cprb(&xcrb); + if (rc) { + DEBUG_ERR( + "pkey_genseckey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n", + (int) cardnr, (int) domain, rc); + goto out; + } + + /* check response returncode and reasoncode */ + if (prepcblk->ccp_rtcode != 0) { + DEBUG_ERR( + "pkey_genseckey secure key generate failure, card response %d/%d\n", + (int) prepcblk->ccp_rtcode, + (int) prepcblk->ccp_rscode); + rc = -EIO; + goto out; + } + + /* process response cprb param block */ + prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepparm = (struct kgrepparm *) prepcblk->rpl_parmb; + + /* check length of the returned secure key token */ + seckeysize = prepparm->lv3.keyblock.toklen + - sizeof(prepparm->lv3.keyblock.toklen) + - sizeof(prepparm->lv3.keyblock.tokattr); + if (seckeysize != SECKEYBLOBSIZE) { + DEBUG_ERR( + "pkey_genseckey secure token size mismatch %d != %d bytes\n", + seckeysize, SECKEYBLOBSIZE); + rc = -EIO; + goto out; + } + + /* check secure key token */ + rc = check_secaeskeytoken(prepparm->lv3.keyblock.tok, 8*keysize); + if (rc) { + rc = -EIO; + goto out; + } + + /* copy the generated secure key token */ + memcpy(seckey->seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE); + +out: + free_cprbmem(mem, PARMBSIZE, 0); + return rc; +} +EXPORT_SYMBOL(pkey_genseckey); + +/* + * Generate an AES secure key with given key value. + */ +int pkey_clr2seckey(u16 cardnr, u16 domain, u32 keytype, + const struct pkey_clrkey *clrkey, + struct pkey_seckey *seckey) +{ + int rc, keysize, seckeysize; + u8 *mem; + struct CPRBX *preqcblk, *prepcblk; + struct ica_xcRB xcrb; + struct cmreqparm { + u8 subfunc_code[2]; + u16 rule_array_len; + char rule_array[8]; + struct lv1 { + u16 len; + u8 clrkey[0]; + } lv1; + struct lv2 { + u16 len; + struct keyid { + u16 len; + u16 attr; + u8 data[SECKEYBLOBSIZE]; + } keyid; + } lv2; + } *preqparm; + struct lv2 *plv2; + struct cmrepparm { + u8 subfunc_code[2]; + u16 rule_array_len; + struct lv3 { + u16 len; + u16 keyblocklen; + struct { + u16 toklen; + u16 tokattr; + u8 tok[0]; + /* ... some more data ... */ + } keyblock; + } lv3; + } *prepparm; + + /* get already prepared memory for 2 cprbs with param block each */ + rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); + if (rc) + return rc; + + /* fill request cprb struct */ + preqcblk->domain = domain; + + /* fill request cprb param block with CM request */ + preqparm = (struct cmreqparm *) preqcblk->req_parmb; + memcpy(preqparm->subfunc_code, "CM", 2); + memcpy(preqparm->rule_array, "AES ", 8); + preqparm->rule_array_len = + sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array); + switch (keytype) { + case PKEY_KEYTYPE_AES_128: + keysize = 16; + break; + case PKEY_KEYTYPE_AES_192: + keysize = 24; + break; + case PKEY_KEYTYPE_AES_256: + keysize = 32; + break; + default: + DEBUG_ERR( + "pkey_clr2seckey unknown/unsupported keytype %d\n", + keytype); + rc = -EINVAL; + goto out; + } + preqparm->lv1.len = sizeof(struct lv1) + keysize; + memcpy(preqparm->lv1.clrkey, clrkey->clrkey, keysize); + plv2 = (struct lv2 *) (((u8 *) &preqparm->lv2) + keysize); + plv2->len = sizeof(struct lv2); + plv2->keyid.len = sizeof(struct keyid); + plv2->keyid.attr = 0x30; + preqcblk->req_parml = sizeof(struct cmreqparm) + keysize; + + /* fill xcrb struct */ + prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); + + /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ + rc = _zcrypt_send_cprb(&xcrb); + if (rc) { + DEBUG_ERR( + "pkey_clr2seckey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n", + (int) cardnr, (int) domain, rc); + goto out; + } + + /* check response returncode and reasoncode */ + if (prepcblk->ccp_rtcode != 0) { + DEBUG_ERR( + "pkey_clr2seckey clear key import failure, card response %d/%d\n", + (int) prepcblk->ccp_rtcode, + (int) prepcblk->ccp_rscode); + rc = -EIO; + goto out; + } + + /* process response cprb param block */ + prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepparm = (struct cmrepparm *) prepcblk->rpl_parmb; + + /* check length of the returned secure key token */ + seckeysize = prepparm->lv3.keyblock.toklen + - sizeof(prepparm->lv3.keyblock.toklen) + - sizeof(prepparm->lv3.keyblock.tokattr); + if (seckeysize != SECKEYBLOBSIZE) { + DEBUG_ERR( + "pkey_clr2seckey secure token size mismatch %d != %d bytes\n", + seckeysize, SECKEYBLOBSIZE); + rc = -EIO; + goto out; + } + + /* check secure key token */ + rc = check_secaeskeytoken(prepparm->lv3.keyblock.tok, 8*keysize); + if (rc) { + rc = -EIO; + goto out; + } + + /* copy the generated secure key token */ + memcpy(seckey->seckey, prepparm->lv3.keyblock.tok, SECKEYBLOBSIZE); + +out: + free_cprbmem(mem, PARMBSIZE, 1); + return rc; +} +EXPORT_SYMBOL(pkey_clr2seckey); + +/* + * Derive a proteced key from the secure key blob. + */ +int pkey_sec2protkey(u16 cardnr, u16 domain, + const struct pkey_seckey *seckey, + struct pkey_protkey *protkey) +{ + int rc; + u8 *mem; + struct CPRBX *preqcblk, *prepcblk; + struct ica_xcRB xcrb; + struct uskreqparm { + u8 subfunc_code[2]; + u16 rule_array_len; + struct lv1 { + u16 len; + u16 attr_len; + u16 attr_flags; + } lv1; + struct lv2 { + u16 len; + u16 attr_len; + u16 attr_flags; + u8 token[0]; /* cca secure key token */ + } lv2 __packed; + } *preqparm; + struct uskrepparm { + u8 subfunc_code[2]; + u16 rule_array_len; + struct lv3 { + u16 len; + u16 attr_len; + u16 attr_flags; + struct cpacfkeyblock { + u8 version; /* version of this struct */ + u8 flags[2]; + u8 algo; + u8 form; + u8 pad1[3]; + u16 keylen; + u8 key[64]; /* the key (keylen bytes) */ + u16 keyattrlen; + u8 keyattr[32]; + u8 pad2[1]; + u8 vptype; + u8 vp[32]; /* verification pattern */ + } keyblock; + } lv3 __packed; + } *prepparm; + + /* get already prepared memory for 2 cprbs with param block each */ + rc = alloc_and_prep_cprbmem(PARMBSIZE, &mem, &preqcblk, &prepcblk); + if (rc) + return rc; + + /* fill request cprb struct */ + preqcblk->domain = domain; + + /* fill request cprb param block with USK request */ + preqparm = (struct uskreqparm *) preqcblk->req_parmb; + memcpy(preqparm->subfunc_code, "US", 2); + preqparm->rule_array_len = sizeof(preqparm->rule_array_len); + preqparm->lv1.len = sizeof(struct lv1); + preqparm->lv1.attr_len = sizeof(struct lv1) - sizeof(preqparm->lv1.len); + preqparm->lv1.attr_flags = 0x0001; + preqparm->lv2.len = sizeof(struct lv2) + SECKEYBLOBSIZE; + preqparm->lv2.attr_len = sizeof(struct lv2) + - sizeof(preqparm->lv2.len) + SECKEYBLOBSIZE; + preqparm->lv2.attr_flags = 0x0000; + memcpy(preqparm->lv2.token, seckey->seckey, SECKEYBLOBSIZE); + preqcblk->req_parml = sizeof(struct uskreqparm) + SECKEYBLOBSIZE; + + /* fill xcrb struct */ + prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); + + /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ + rc = _zcrypt_send_cprb(&xcrb); + if (rc) { + DEBUG_ERR( + "pkey_sec2protkey zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n", + (int) cardnr, (int) domain, rc); + goto out; + } + + /* check response returncode and reasoncode */ + if (prepcblk->ccp_rtcode != 0) { + DEBUG_ERR( + "pkey_sec2protkey unwrap secure key failure, card response %d/%d\n", + (int) prepcblk->ccp_rtcode, + (int) prepcblk->ccp_rscode); + rc = -EIO; + goto out; + } + + /* process response cprb param block */ + prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepparm = (struct uskrepparm *) prepcblk->rpl_parmb; + + /* check the returned keyblock */ + if (prepparm->lv3.keyblock.version != 0x01) { + DEBUG_ERR( + "pkey_sec2protkey reply param keyblock version mismatch 0x%02x != 0x01\n", + (int) prepparm->lv3.keyblock.version); + rc = -EIO; + goto out; + } + + /* copy the tanslated protected key */ + switch (prepparm->lv3.keyblock.keylen) { + case 16+32: + protkey->type = PKEY_KEYTYPE_AES_128; + break; + case 24+32: + protkey->type = PKEY_KEYTYPE_AES_192; + break; + case 32+32: + protkey->type = PKEY_KEYTYPE_AES_256; + break; + default: + DEBUG_ERR("pkey_sec2protkey unknown/unsupported keytype %d\n", + prepparm->lv3.keyblock.keylen); + rc = -EIO; + goto out; + } + protkey->len = prepparm->lv3.keyblock.keylen; + memcpy(protkey->protkey, prepparm->lv3.keyblock.key, protkey->len); + +out: + free_cprbmem(mem, PARMBSIZE, 0); + return rc; +} +EXPORT_SYMBOL(pkey_sec2protkey); + +/* + * Create a protected key from a clear key value. + */ +int pkey_clr2protkey(u32 keytype, + const struct pkey_clrkey *clrkey, + struct pkey_protkey *protkey) +{ + long fc; + int keysize; + u8 paramblock[64]; + + switch (keytype) { + case PKEY_KEYTYPE_AES_128: + keysize = 16; + fc = CPACF_PCKMO_ENC_AES_128_KEY; + break; + case PKEY_KEYTYPE_AES_192: + keysize = 24; + fc = CPACF_PCKMO_ENC_AES_192_KEY; + break; + case PKEY_KEYTYPE_AES_256: + keysize = 32; + fc = CPACF_PCKMO_ENC_AES_256_KEY; + break; + default: + DEBUG_ERR("pkey_clr2protkey unknown/unsupported keytype %d\n", + keytype); + return -EINVAL; + } + + /* prepare param block */ + memset(paramblock, 0, sizeof(paramblock)); + memcpy(paramblock, clrkey->clrkey, keysize); + + /* call the pckmo instruction */ + cpacf_pckmo(fc, paramblock); + + /* copy created protected key */ + protkey->type = keytype; + protkey->len = keysize + 32; + memcpy(protkey->protkey, paramblock, keysize + 32); + + return 0; +} +EXPORT_SYMBOL(pkey_clr2protkey); + +/* + * query cryptographic facility from adapter + */ +static int query_crypto_facility(u16 cardnr, u16 domain, + const char *keyword, + u8 *rarray, size_t *rarraylen, + u8 *varray, size_t *varraylen) +{ + int rc; + u16 len; + u8 *mem, *ptr; + struct CPRBX *preqcblk, *prepcblk; + struct ica_xcRB xcrb; + struct fqreqparm { + u8 subfunc_code[2]; + u16 rule_array_len; + char rule_array[8]; + struct lv1 { + u16 len; + u8 data[VARDATASIZE]; + } lv1; + u16 dummylen; + } *preqparm; + size_t parmbsize = sizeof(struct fqreqparm); + struct fqrepparm { + u8 subfunc_code[2]; + u8 lvdata[0]; + } *prepparm; + + /* get already prepared memory for 2 cprbs with param block each */ + rc = alloc_and_prep_cprbmem(parmbsize, &mem, &preqcblk, &prepcblk); + if (rc) + return rc; + + /* fill request cprb struct */ + preqcblk->domain = domain; + + /* fill request cprb param block with FQ request */ + preqparm = (struct fqreqparm *) preqcblk->req_parmb; + memcpy(preqparm->subfunc_code, "FQ", 2); + strncpy(preqparm->rule_array, keyword, sizeof(preqparm->rule_array)); + preqparm->rule_array_len = + sizeof(preqparm->rule_array_len) + sizeof(preqparm->rule_array); + preqparm->lv1.len = sizeof(preqparm->lv1); + preqparm->dummylen = sizeof(preqparm->dummylen); + preqcblk->req_parml = parmbsize; + + /* fill xcrb struct */ + prep_xcrb(&xcrb, cardnr, preqcblk, prepcblk); + + /* forward xcrb with request CPRB and reply CPRB to zcrypt dd */ + rc = _zcrypt_send_cprb(&xcrb); + if (rc) { + DEBUG_ERR( + "query_crypto_facility zcrypt_send_cprb (cardnr=%d domain=%d) failed with errno %d\n", + (int) cardnr, (int) domain, rc); + goto out; + } + + /* check response returncode and reasoncode */ + if (prepcblk->ccp_rtcode != 0) { + DEBUG_ERR( + "query_crypto_facility unwrap secure key failure, card response %d/%d\n", + (int) prepcblk->ccp_rtcode, + (int) prepcblk->ccp_rscode); + rc = -EIO; + goto out; + } + + /* process response cprb param block */ + prepcblk->rpl_parmb = ((u8 *) prepcblk) + sizeof(struct CPRBX); + prepparm = (struct fqrepparm *) prepcblk->rpl_parmb; + ptr = prepparm->lvdata; + + /* check and possibly copy reply rule array */ + len = *((u16 *) ptr); + if (len > sizeof(u16)) { + ptr += sizeof(u16); + len -= sizeof(u16); + if (rarray && rarraylen && *rarraylen > 0) { + *rarraylen = (len > *rarraylen ? *rarraylen : len); + memcpy(rarray, ptr, *rarraylen); + } + ptr += len; + } + /* check and possible copy reply var array */ + len = *((u16 *) ptr); + if (len > sizeof(u16)) { + ptr += sizeof(u16); + len -= sizeof(u16); + if (varray && varraylen && *varraylen > 0) { + *varraylen = (len > *varraylen ? *varraylen : len); + memcpy(varray, ptr, *varraylen); + } + ptr += len; + } + +out: + free_cprbmem(mem, parmbsize, 0); + return rc; +} + +/* + * Fetch just the mkvp value via query_crypto_facility from adapter. + */ +static int fetch_mkvp(u16 cardnr, u16 domain, u64 *mkvp) +{ + int rc, found = 0; + size_t rlen, vlen; + u8 *rarray, *varray, *pg; + + pg = (u8 *) __get_free_page(GFP_KERNEL); + if (!pg) + return -ENOMEM; + rarray = pg; + varray = pg + PAGE_SIZE/2; + rlen = vlen = PAGE_SIZE/2; + + rc = query_crypto_facility(cardnr, domain, "STATICSA", + rarray, &rlen, varray, &vlen); + if (rc == 0 && rlen > 8*8 && vlen > 184+8) { + if (rarray[64] == '2') { + /* current master key state is valid */ + *mkvp = *((u64 *)(varray + 184)); + found = 1; + } + } + + free_page((unsigned long) pg); + + return found ? 0 : -ENOENT; +} + +/* struct to hold cached mkvp info for each card/domain */ +struct mkvp_info { + struct list_head list; + u16 cardnr; + u16 domain; + u64 mkvp; +}; + +/* a list with mkvp_info entries */ +static LIST_HEAD(mkvp_list); +static DEFINE_SPINLOCK(mkvp_list_lock); + +static int mkvp_cache_fetch(u16 cardnr, u16 domain, u64 *mkvp) +{ + int rc = -ENOENT; + struct mkvp_info *ptr; + + spin_lock_bh(&mkvp_list_lock); + list_for_each_entry(ptr, &mkvp_list, list) { + if (ptr->cardnr == cardnr && + ptr->domain == domain) { + *mkvp = ptr->mkvp; + rc = 0; + break; + } + } + spin_unlock_bh(&mkvp_list_lock); + + return rc; +} + +static void mkvp_cache_update(u16 cardnr, u16 domain, u64 mkvp) +{ + int found = 0; + struct mkvp_info *ptr; + + spin_lock_bh(&mkvp_list_lock); + list_for_each_entry(ptr, &mkvp_list, list) { + if (ptr->cardnr == cardnr && + ptr->domain == domain) { + ptr->mkvp = mkvp; + found = 1; + break; + } + } + if (!found) { + ptr = kmalloc(sizeof(*ptr), GFP_ATOMIC); + if (!ptr) { + spin_unlock_bh(&mkvp_list_lock); + return; + } + ptr->cardnr = cardnr; + ptr->domain = domain; + ptr->mkvp = mkvp; + list_add(&ptr->list, &mkvp_list); + } + spin_unlock_bh(&mkvp_list_lock); +} + +static void mkvp_cache_scrub(u16 cardnr, u16 domain) +{ + struct mkvp_info *ptr; + + spin_lock_bh(&mkvp_list_lock); + list_for_each_entry(ptr, &mkvp_list, list) { + if (ptr->cardnr == cardnr && + ptr->domain == domain) { + list_del(&ptr->list); + kfree(ptr); + break; + } + } + spin_unlock_bh(&mkvp_list_lock); +} + +static void __exit mkvp_cache_free(void) +{ + struct mkvp_info *ptr, *pnext; + + spin_lock_bh(&mkvp_list_lock); + list_for_each_entry_safe(ptr, pnext, &mkvp_list, list) { + list_del(&ptr->list); + kfree(ptr); + } + spin_unlock_bh(&mkvp_list_lock); +} + +/* + * Search for a matching crypto card based on the Master Key + * Verification Pattern provided inside a secure key. + */ +int pkey_findcard(const struct pkey_seckey *seckey, + u16 *pcardnr, u16 *pdomain, int verify) +{ + struct secaeskeytoken *t = (struct secaeskeytoken *) seckey; + struct zcrypt_device_matrix *device_matrix; + u16 card, dom; + u64 mkvp; + int i, rc; + + /* mkvp must not be zero */ + if (t->mkvp == 0) + return -EINVAL; + + /* fetch status of all crypto cards */ + device_matrix = kmalloc(sizeof(struct zcrypt_device_matrix), + GFP_KERNEL); + if (!device_matrix) + return -ENOMEM; + zcrypt_device_status_mask(device_matrix); + + /* walk through all crypto cards */ + for (i = 0; i < MAX_ZDEV_ENTRIES; i++) { + card = AP_QID_CARD(device_matrix->device[i].qid); + dom = AP_QID_QUEUE(device_matrix->device[i].qid); + if (device_matrix->device[i].online && + device_matrix->device[i].functions & 0x04) { + /* an enabled CCA Coprocessor card */ + /* try cached mkvp */ + if (mkvp_cache_fetch(card, dom, &mkvp) == 0 && + t->mkvp == mkvp) { + if (!verify) + break; + /* verify: fetch mkvp from adapter */ + if (fetch_mkvp(card, dom, &mkvp) == 0) { + mkvp_cache_update(card, dom, mkvp); + if (t->mkvp == mkvp) + break; + } + } + } else { + /* Card is offline and/or not a CCA card. */ + /* del mkvp entry from cache if it exists */ + mkvp_cache_scrub(card, dom); + } + } + if (i >= MAX_ZDEV_ENTRIES) { + /* nothing found, so this time without cache */ + for (i = 0; i < MAX_ZDEV_ENTRIES; i++) { + if (!(device_matrix->device[i].online && + device_matrix->device[i].functions & 0x04)) + continue; + card = AP_QID_CARD(device_matrix->device[i].qid); + dom = AP_QID_QUEUE(device_matrix->device[i].qid); + /* fresh fetch mkvp from adapter */ + if (fetch_mkvp(card, dom, &mkvp) == 0) { + mkvp_cache_update(card, dom, mkvp); + if (t->mkvp == mkvp) + break; + } + } + } + if (i < MAX_ZDEV_ENTRIES) { + if (pcardnr) + *pcardnr = card; + if (pdomain) + *pdomain = dom; + rc = 0; + } else + rc = -ENODEV; + + kfree(device_matrix); + return rc; +} +EXPORT_SYMBOL(pkey_findcard); + +/* + * Find card and transform secure key into protected key. + */ +int pkey_skey2pkey(const struct pkey_seckey *seckey, + struct pkey_protkey *protkey) +{ + u16 cardnr, domain; + int rc, verify; + + /* + * The pkey_sec2protkey call may fail when a card has been + * addressed where the master key was changed after last fetch + * of the mkvp into the cache. So first try without verify then + * with verify enabled (thus refreshing the mkvp for each card). + */ + for (verify = 0; verify < 2; verify++) { + rc = pkey_findcard(seckey, &cardnr, &domain, verify); + if (rc) + continue; + rc = pkey_sec2protkey(cardnr, domain, seckey, protkey); + if (rc == 0) + break; + } + + if (rc) + DEBUG_DBG("pkey_skey2pkey failed rc=%d\n", rc); + + return rc; +} +EXPORT_SYMBOL(pkey_skey2pkey); + +/* + * File io functions + */ + +static long pkey_unlocked_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + int rc; + + switch (cmd) { + case PKEY_GENSECK: { + struct pkey_genseck __user *ugs = (void __user *) arg; + struct pkey_genseck kgs; + + if (copy_from_user(&kgs, ugs, sizeof(kgs))) + return -EFAULT; + rc = pkey_genseckey(kgs.cardnr, kgs.domain, + kgs.keytype, &kgs.seckey); + DEBUG_DBG("pkey_ioctl pkey_genseckey()=%d\n", rc); + if (rc) + break; + if (copy_to_user(ugs, &kgs, sizeof(kgs))) + return -EFAULT; + break; + } + case PKEY_CLR2SECK: { + struct pkey_clr2seck __user *ucs = (void __user *) arg; + struct pkey_clr2seck kcs; + + if (copy_from_user(&kcs, ucs, sizeof(kcs))) + return -EFAULT; + rc = pkey_clr2seckey(kcs.cardnr, kcs.domain, kcs.keytype, + &kcs.clrkey, &kcs.seckey); + DEBUG_DBG("pkey_ioctl pkey_clr2seckey()=%d\n", rc); + if (rc) + break; + if (copy_to_user(ucs, &kcs, sizeof(kcs))) + return -EFAULT; + memzero_explicit(&kcs, sizeof(kcs)); + break; + } + case PKEY_SEC2PROTK: { + struct pkey_sec2protk __user *usp = (void __user *) arg; + struct pkey_sec2protk ksp; + + if (copy_from_user(&ksp, usp, sizeof(ksp))) + return -EFAULT; + rc = pkey_sec2protkey(ksp.cardnr, ksp.domain, + &ksp.seckey, &ksp.protkey); + DEBUG_DBG("pkey_ioctl pkey_sec2protkey()=%d\n", rc); + if (rc) + break; + if (copy_to_user(usp, &ksp, sizeof(ksp))) + return -EFAULT; + break; + } + case PKEY_CLR2PROTK: { + struct pkey_clr2protk __user *ucp = (void __user *) arg; + struct pkey_clr2protk kcp; + + if (copy_from_user(&kcp, ucp, sizeof(kcp))) + return -EFAULT; + rc = pkey_clr2protkey(kcp.keytype, + &kcp.clrkey, &kcp.protkey); + DEBUG_DBG("pkey_ioctl pkey_clr2protkey()=%d\n", rc); + if (rc) + break; + if (copy_to_user(ucp, &kcp, sizeof(kcp))) + return -EFAULT; + memzero_explicit(&kcp, sizeof(kcp)); + break; + } + case PKEY_FINDCARD: { + struct pkey_findcard __user *ufc = (void __user *) arg; + struct pkey_findcard kfc; + + if (copy_from_user(&kfc, ufc, sizeof(kfc))) + return -EFAULT; + rc = pkey_findcard(&kfc.seckey, + &kfc.cardnr, &kfc.domain, 1); + DEBUG_DBG("pkey_ioctl pkey_findcard()=%d\n", rc); + if (rc) + break; + if (copy_to_user(ufc, &kfc, sizeof(kfc))) + return -EFAULT; + break; + } + case PKEY_SKEY2PKEY: { + struct pkey_skey2pkey __user *usp = (void __user *) arg; + struct pkey_skey2pkey ksp; + + if (copy_from_user(&ksp, usp, sizeof(ksp))) + return -EFAULT; + rc = pkey_skey2pkey(&ksp.seckey, &ksp.protkey); + DEBUG_DBG("pkey_ioctl pkey_skey2pkey()=%d\n", rc); + if (rc) + break; + if (copy_to_user(usp, &ksp, sizeof(ksp))) + return -EFAULT; + break; + } + default: + /* unknown/unsupported ioctl cmd */ + return -ENOTTY; + } + + return rc; +} + +/* + * Sysfs and file io operations + */ +static const struct file_operations pkey_fops = { + .owner = THIS_MODULE, + .open = nonseekable_open, + .llseek = no_llseek, + .unlocked_ioctl = pkey_unlocked_ioctl, +}; + +static struct miscdevice pkey_dev = { + .name = "pkey", + .minor = MISC_DYNAMIC_MINOR, + .mode = 0666, + .fops = &pkey_fops, +}; + +/* + * Module init + */ +int __init pkey_init(void) +{ + cpacf_mask_t pckmo_functions; + + /* check for pckmo instructions available */ + if (!cpacf_query(CPACF_PCKMO, &pckmo_functions)) + return -EOPNOTSUPP; + if (!cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_128_KEY) || + !cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_192_KEY) || + !cpacf_test_func(&pckmo_functions, CPACF_PCKMO_ENC_AES_256_KEY)) + return -EOPNOTSUPP; + + pkey_debug_init(); + + return misc_register(&pkey_dev); +} + +/* + * Module exit + */ +static void __exit pkey_exit(void) +{ + misc_deregister(&pkey_dev); + mkvp_cache_free(); + pkey_debug_exit(); +} + +module_init(pkey_init); +module_exit(pkey_exit); diff --git a/drivers/s390/crypto/zcrypt_api.c b/drivers/s390/crypto/zcrypt_api.c index 144a17941e6f..93015f85d4a6 100644 --- a/drivers/s390/crypto/zcrypt_api.c +++ b/drivers/s390/crypto/zcrypt_api.c @@ -374,7 +374,7 @@ out: return rc; } -static long zcrypt_send_cprb(struct ica_xcRB *xcRB) +long zcrypt_send_cprb(struct ica_xcRB *xcRB) { struct zcrypt_card *zc, *pref_zc; struct zcrypt_queue *zq, *pref_zq; @@ -444,6 +444,7 @@ out: AP_QID_CARD(qid), AP_QID_QUEUE(qid)); return rc; } +EXPORT_SYMBOL(zcrypt_send_cprb); static bool is_desired_ep11_card(unsigned int dev_id, unsigned short target_num, @@ -619,7 +620,7 @@ out: return rc; } -static void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix) +void zcrypt_device_status_mask(struct zcrypt_device_matrix *matrix) { struct zcrypt_card *zc; struct zcrypt_queue *zq; diff --git a/drivers/s390/crypto/zcrypt_api.h b/drivers/s390/crypto/zcrypt_api.h index 274a59051534..6c94efd23eac 100644 --- a/drivers/s390/crypto/zcrypt_api.h +++ b/drivers/s390/crypto/zcrypt_api.h @@ -190,5 +190,7 @@ void zcrypt_msgtype_unregister(struct zcrypt_ops *); struct zcrypt_ops *zcrypt_msgtype(unsigned char *, int); int zcrypt_api_init(void); void zcrypt_api_exit(void); +long zcrypt_send_cprb(struct ica_xcRB *xcRB); +void zcrypt_device_status_mask(struct zcrypt_device_matrix *devstatus); #endif /* _ZCRYPT_API_H_ */ diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c index 137d22d3a005..838347c44f32 100644 --- a/drivers/scsi/aacraid/linit.c +++ b/drivers/scsi/aacraid/linit.c @@ -1630,7 +1630,7 @@ static int aac_acquire_resources(struct aac_dev *dev) if (!dev->sync_mode) { /* After EEH recovery or suspend resume, max_msix count - * may change, therfore updating in init as well. + * may change, therefore updating in init as well. */ dev->init->r7.no_of_msix_vectors = cpu_to_le32(dev->max_msix); aac_adapter_start(dev); diff --git a/drivers/scsi/bfa/bfi_ms.h b/drivers/scsi/bfa/bfi_ms.h index ae5bfe039fcc..ccbd9e31a5de 100644 --- a/drivers/scsi/bfa/bfi_ms.h +++ b/drivers/scsi/bfa/bfi_ms.h @@ -680,7 +680,7 @@ struct bfi_ioim_req_s { /* * SG elements array within the IO request must be double word - * aligned. This aligment is required to optimize SGM setup for the IO. + * aligned. This alignment is required to optimize SGM setup for the IO. */ struct bfi_sge_s sges[BFI_SGE_INLINE_MAX]; u8 io_timeout; diff --git a/drivers/scsi/fcoe/fcoe_ctlr.c b/drivers/scsi/fcoe/fcoe_ctlr.c index cea57e27e713..656463ff9ccb 100644 --- a/drivers/scsi/fcoe/fcoe_ctlr.c +++ b/drivers/scsi/fcoe/fcoe_ctlr.c @@ -1387,7 +1387,7 @@ static void fcoe_ctlr_recv_clr_vlink(struct fcoe_ctlr *fip, /* * Actually need to subtract 'sizeof(*mp) - sizeof(*wp)' from 'rlen' * before determining max Vx_Port descriptor but a buggy FCF could have - * omited either or both MAC Address and Name Identifier descriptors + * omitted either or both MAC Address and Name Identifier descriptors */ num_vlink_desc = rlen / sizeof(*vp); if (num_vlink_desc) diff --git a/drivers/scsi/ipr.c b/drivers/scsi/ipr.c index 835c59c777f2..b29afafc2885 100644 --- a/drivers/scsi/ipr.c +++ b/drivers/scsi/ipr.c @@ -9330,7 +9330,7 @@ static pci_ers_result_t ipr_pci_error_detected(struct pci_dev *pdev, * ipr_probe_ioa_part2 - Initializes IOAs found in ipr_probe_ioa(..) * @ioa_cfg: ioa cfg struct * - * Description: This is the second phase of adapter intialization + * Description: This is the second phase of adapter initialization * This function takes care of initilizing the adapter to the point * where it can accept new commands. diff --git a/drivers/scsi/lpfc/lpfc_attr.c b/drivers/scsi/lpfc/lpfc_attr.c index 50cf402dea29..03cb05abc821 100644 --- a/drivers/scsi/lpfc/lpfc_attr.c +++ b/drivers/scsi/lpfc/lpfc_attr.c @@ -3329,7 +3329,7 @@ static DEVICE_ATTR(lpfc_static_vport, S_IRUGO, * @buf: Data buffer. * @count: Size of the data buffer. * - * This function get called when an user write to the lpfc_stat_data_ctrl + * This function get called when a user write to the lpfc_stat_data_ctrl * sysfs file. This function parse the command written to the sysfs file * and take appropriate action. These commands are used for controlling * driver statistical data collection. diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index d977a472f89f..8e886caf2454 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c @@ -4510,7 +4510,7 @@ lpfc_sli4_rb_setup(struct lpfc_hba *phba) * @phba: Pointer to HBA context object. * @sli_mode: sli mode - 2/3 * - * This function is called by the sli intialization code path + * This function is called by the sli initialization code path * to issue config_port mailbox command. This function restarts the * HBA firmware and issues a config_port mailbox command to configure * the SLI interface in the sli mode specified by sli_mode @@ -4650,11 +4650,11 @@ do_prep_failed: /** - * lpfc_sli_hba_setup - SLI intialization function + * lpfc_sli_hba_setup - SLI initialization function * @phba: Pointer to HBA context object. * - * This function is the main SLI intialization function. This function - * is called by the HBA intialization code, HBA reset code and HBA + * This function is the main SLI initialization function. This function + * is called by the HBA initialization code, HBA reset code and HBA * error attention handler code. Caller is not required to hold any * locks. This function issues config_port mailbox command to configure * the SLI, setup iocb rings and HBQ rings. In the end the function @@ -6324,11 +6324,11 @@ lpfc_set_host_data(struct lpfc_hba *phba, LPFC_MBOXQ_t *mbox) } /** - * lpfc_sli4_hba_setup - SLI4 device intialization PCI function + * lpfc_sli4_hba_setup - SLI4 device initialization PCI function * @phba: Pointer to HBA context object. * - * This function is the main SLI4 device intialization PCI function. This - * function is called by the HBA intialization code, HBA reset code and + * This function is the main SLI4 device initialization PCI function. This + * function is called by the HBA initialization code, HBA reset code and * HBA error attention handler code. Caller is not required to hold any * locks. **/ @@ -12079,7 +12079,7 @@ lpfc_sli4_sp_handle_els_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, * @phba: Pointer to HBA context object. * @wcqe: Pointer to work-queue completion queue entry. * - * This routine handles slow-path WQ entry comsumed event by invoking the + * This routine handles slow-path WQ entry consumed event by invoking the * proper WQ release routine to the slow-path WQ. **/ static void @@ -12451,7 +12451,7 @@ lpfc_sli4_fp_handle_fcp_wcqe(struct lpfc_hba *phba, struct lpfc_queue *cq, * @cq: Pointer to completion queue. * @wcqe: Pointer to work-queue completion queue entry. * - * This routine handles an fast-path WQ entry comsumed event by invoking the + * This routine handles an fast-path WQ entry consumed event by invoking the * proper WQ release routine to the slow-path WQ. **/ static void diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 02fe1c4aae2f..bdffb692bded 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -1925,7 +1925,7 @@ mpt3sas_send_diag_release(struct MPT3SAS_ADAPTER *ioc, u8 buffer_type, * * This allows ownership of the specified buffer to returned to the driver, * allowing an application to read the buffer without fear that firmware is - * overwritting information in the buffer. + * overwriting information in the buffer. */ static long _ctl_diag_release(struct MPT3SAS_ADAPTER *ioc, void __user *arg) diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.h b/drivers/scsi/mpt3sas/mpt3sas_ctl.h index f3e17a8c1b07..a44046cff0f3 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.h +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.h @@ -390,7 +390,7 @@ struct mpt3_diag_query { * * This allows ownership of the specified buffer to returned to the driver, * allowing an application to read the buffer without fear that firmware is - * overwritting information in the buffer. + * overwriting information in the buffer. */ struct mpt3_diag_release { struct mpt3_ioctl_header hdr; diff --git a/drivers/scsi/osd/osd_initiator.c b/drivers/scsi/osd/osd_initiator.c index 30b905080c61..6903f03c88af 100644 --- a/drivers/scsi/osd/osd_initiator.c +++ b/drivers/scsi/osd/osd_initiator.c @@ -1290,7 +1290,7 @@ int osd_req_add_get_attr_list(struct osd_request *or, or->enc_get_attr.total_bytes = total_bytes; OSD_DEBUG( - "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%Zu)\n", + "get_attr.total_bytes=%u(%u) enc_get_attr.total_bytes=%u(%zu)\n", or->get_attr.total_bytes, or->get_attr.total_bytes - _osd_req_sizeof_alist_header(or), or->enc_get_attr.total_bytes, @@ -1677,7 +1677,7 @@ int osd_finalize_request(struct osd_request *or, } } else { /* TODO: I think that for the GET_ATTR command these 2 should - * be reversed to keep them in execution order (for embeded + * be reversed to keep them in execution order (for embedded * targets with low memory footprint) */ ret = _osd_req_finalize_set_attr_list(or); diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 451de6c5e3c9..75ac662793a3 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c @@ -3435,7 +3435,7 @@ static ssize_t osst_write(struct file * filp, const char __user * buf, size_t co /* Write must be integral number of blocks */ if (STp->block_size != 0 && (count % STp->block_size) != 0) { - printk(KERN_ERR "%s:E: Write (%Zd bytes) not multiple of tape block size (%d%c).\n", + printk(KERN_ERR "%s:E: Write (%zd bytes) not multiple of tape block size (%d%c).\n", name, count, STp->block_size<1024? STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); retval = (-EINVAL); @@ -3756,7 +3756,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo if ((count % STp->block_size) != 0) { printk(KERN_WARNING - "%s:W: Read (%Zd bytes) not multiple of tape block size (%d%c).\n", name, count, + "%s:W: Read (%zd bytes) not multiple of tape block size (%d%c).\n", name, count, STp->block_size<1024?STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); } @@ -3815,7 +3815,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo if (transfer == 0) { printk(KERN_WARNING - "%s:W: Nothing can be transferred, requested %Zd, tape block size (%d%c).\n", + "%s:W: Nothing can be transferred, requested %zd, tape block size (%d%c).\n", name, count, STp->block_size < 1024? STp->block_size:STp->block_size/1024, STp->block_size<1024?'b':'k'); diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 7b6317c8c2e9..265e1395bdb8 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c @@ -5669,7 +5669,7 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) /* Validate firmware image by checking version. */ if (blob->fw->size < 8 * sizeof(uint16_t)) { ql_log(ql_log_fatal, vha, 0x0085, - "Unable to verify integrity of firmware image (%Zd).\n", + "Unable to verify integrity of firmware image (%zd).\n", blob->fw->size); goto fail_fw_integrity; } @@ -5697,7 +5697,7 @@ qla2x00_load_risc(scsi_qla_host_t *vha, uint32_t *srisc_addr) if (blob->fw->size < fwclen) { ql_log(ql_log_fatal, vha, 0x0088, "Unable to verify integrity of firmware image " - "(%Zd).\n", blob->fw->size); + "(%zd).\n", blob->fw->size); goto fail_fw_integrity; } @@ -5778,7 +5778,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) /* Validate firmware image by checking version. */ if (blob->fw->size < 8 * sizeof(uint32_t)) { ql_log(ql_log_fatal, vha, 0x0093, - "Unable to verify integrity of firmware image (%Zd).\n", + "Unable to verify integrity of firmware image (%zd).\n", blob->fw->size); return QLA_FUNCTION_FAILED; } @@ -5789,7 +5789,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) (dcode[0] == 0 && dcode[1] == 0 && dcode[2] == 0 && dcode[3] == 0)) { ql_log(ql_log_fatal, vha, 0x0094, - "Unable to verify integrity of firmware image (%Zd).\n", + "Unable to verify integrity of firmware image (%zd).\n", blob->fw->size); ql_log(ql_log_fatal, vha, 0x0095, "Firmware data: %08x %08x %08x %08x.\n", @@ -5807,7 +5807,7 @@ qla24xx_load_risc_blob(scsi_qla_host_t *vha, uint32_t *srisc_addr) if (blob->fw->size < fwclen) { ql_log(ql_log_fatal, vha, 0x0096, "Unable to verify integrity of firmware image " - "(%Zd).\n", blob->fw->size); + "(%zd).\n", blob->fw->size); return QLA_FUNCTION_FAILED; } diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c index f94535130a34..cdbb293aca08 100644 --- a/drivers/scsi/scsi_transport_sas.c +++ b/drivers/scsi/scsi_transport_sas.c @@ -1475,7 +1475,7 @@ static void sas_end_device_release(struct device *dev) } /** - * sas_rphy_initialize - common rphy intialization + * sas_rphy_initialize - common rphy initialization * @rphy: rphy to initialise * * Used by both sas_end_device_alloc() and sas_expander_alloc() to diff --git a/drivers/scsi/storvsc_drv.c b/drivers/scsi/storvsc_drv.c index 585e54f6512c..638e5f427c90 100644 --- a/drivers/scsi/storvsc_drv.c +++ b/drivers/scsi/storvsc_drv.c @@ -280,7 +280,7 @@ static const struct vmstor_protocol vmstor_protocols[] = { /* - * This structure is sent during the intialization phase to get the different + * This structure is sent during the initialization phase to get the different * properties of the channel. */ diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h index 7b8cc3a25214..cd1eb2c4c940 100644 --- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.h +++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.h @@ -39,7 +39,7 @@ struct fpgaimage { const struct firmware *fw_entry; /* - * the followings can be read from bitstream, + * the following can be read from bitstream, * but other image format should have as well */ char filename[MAX_STR]; diff --git a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h index b0eb80d70c23..60b827eeefe2 100644 --- a/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h +++ b/drivers/staging/lustre/lustre/include/lustre/lustre_idl.h @@ -1704,7 +1704,7 @@ struct ost_lvb { * lquota data structures */ -/* The lquota_id structure is an union of all the possible identifier types that +/* The lquota_id structure is a union of all the possible identifier types that * can be used with quota, this includes: * - 64-bit user ID * - 64-bit group ID diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211.h b/drivers/staging/rtl8192u/ieee80211/ieee80211.h index 0d247058bce4..097147071df0 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211.h +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211.h @@ -1953,7 +1953,7 @@ struct ieee80211_device { /* ask to the driver to retune the radio . * This function can sleep. the driver should ensure - * the radio has been swithced before return. + * the radio has been switched before return. */ void (*set_chan)(struct net_device *dev, short ch); @@ -1964,7 +1964,7 @@ struct ieee80211_device { * The syncro version is similar to the start_scan but * does not return until all channels has been scanned. * this is called in user context and should sleep, - * it is called in a work_queue when swithcing to ad-hoc mode + * it is called in a work_queue when switching to ad-hoc mode * or in behalf of iwlist scan when the card is associated * and root user ask for a scan. * the function stop_scan should stop both the syncro and diff --git a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c index 1bff0e91cc0c..0ea90aae4283 100644 --- a/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c +++ b/drivers/staging/rtl8192u/ieee80211/ieee80211_softmac.c @@ -2364,7 +2364,7 @@ static void ieee80211_start_ibss_wq(struct work_struct *work) // if((IS_DOT11D_ENABLE(ieee)) && (ieee->state == IEEE80211_NOLINK)) if (ieee->state == IEEE80211_NOLINK) ieee->current_network.channel = 6; - /* if not then the state is not linked. Maybe the user swithced to + /* if not then the state is not linked. Maybe the user switched to * ad-hoc mode just after being in monitor mode, or just after * being very few time in managed mode (so the card have had no * time to scan all the chans..) or we have just run up the iface diff --git a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c index 1dc8627e65b0..cb0b7ca36b1e 100644 --- a/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c +++ b/drivers/staging/vc04_services/interface/vchiq_arm/vchiq_arm.c @@ -1875,8 +1875,8 @@ vchiq_arm_init_state(VCHIQ_STATE_T *state, VCHIQ_ARM_STATE_T *arm_state) ** ** VC_RESUME_IDLE - Initialise the resume completion at the same time. The ** resume completion is in it's 'done' state whenever -** videcore is running. Therfore, the VC_RESUME_IDLE state -** implies that videocore is suspended. +** videcore is running. Therefore, the VC_RESUME_IDLE +** state implies that videocore is suspended. ** Hence, any thread which needs to wait until videocore is ** running can wait on this completion - it will only block ** if videocore is suspended. diff --git a/drivers/staging/wilc1000/linux_wlan.c b/drivers/staging/wilc1000/linux_wlan.c index 9ab43935869e..2eebc6215cac 100644 --- a/drivers/staging/wilc1000/linux_wlan.c +++ b/drivers/staging/wilc1000/linux_wlan.c @@ -213,7 +213,7 @@ static void deinit_irq(struct net_device *dev) vif = netdev_priv(dev); wilc = vif->wilc; - /* Deintialize IRQ */ + /* Deinitialize IRQ */ if (wilc->dev_irq_num) { free_irq(wilc->dev_irq_num, wilc); gpio_free(wilc->gpio); diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c index f7ce47cac2aa..7961d1c56847 100644 --- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c +++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c @@ -2357,7 +2357,7 @@ int wilc_deinit_host_int(struct net_device *net) del_timer_sync(&wilc_during_ip_timer); if (s32Error) - netdev_err(net, "Error while deintializing host interface\n"); + netdev_err(net, "Error while deinitializing host interface\n"); return s32Error; } diff --git a/drivers/target/target_core_user.c b/drivers/target/target_core_user.c index 5c1cb2df3a54..c3adefe95e50 100644 --- a/drivers/target/target_core_user.c +++ b/drivers/target/target_core_user.c @@ -642,9 +642,7 @@ static unsigned int tcmu_handle_completions(struct tcmu_dev *udev) WARN_ON(tcmu_hdr_get_op(entry->hdr.len_op) != TCMU_OP_CMD); spin_lock(&udev->commands_lock); - cmd = idr_find(&udev->commands, entry->hdr.cmd_id); - if (cmd) - idr_remove(&udev->commands, cmd->cmd_id); + cmd = idr_remove(&udev->commands, entry->hdr.cmd_id); spin_unlock(&udev->commands_lock); if (!cmd) { diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index eb278832f5ce..1bacbc3b19a0 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -667,7 +667,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, struct n_hdlc_buf *tbuf; if (debuglevel >= DEBUG_LEVEL_INFO) - printk("%s(%d)n_hdlc_tty_write() called count=%Zd\n", + printk("%s(%d)n_hdlc_tty_write() called count=%zd\n", __FILE__,__LINE__,count); /* Verify pointers */ diff --git a/drivers/tty/serial/ioc4_serial.c b/drivers/tty/serial/ioc4_serial.c index 6ad26f802b51..f96bcf9bee25 100644 --- a/drivers/tty/serial/ioc4_serial.c +++ b/drivers/tty/serial/ioc4_serial.c @@ -210,7 +210,7 @@ #define IOC4_SSCR_PAUSE_STATE 0x40000000 /* Sets when PAUSE takes effect */ #define IOC4_SSCR_RESET 0x80000000 /* Reset DMA channels */ -/* All producer/comsumer pointers are the same bitfield */ +/* All producer/consumer pointers are the same bitfield */ #define IOC4_PROD_CONS_PTR_4K 0x00000ff8 /* For 4K buffers */ #define IOC4_PROD_CONS_PTR_1K 0x000003f8 /* For 1K buffers */ #define IOC4_PROD_CONS_PTR_OFF 3 diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c index 52747b6ac89a..ca425e8099ea 100644 --- a/drivers/usb/core/devio.c +++ b/drivers/usb/core/devio.c @@ -2335,7 +2335,7 @@ static int proc_drop_privileges(struct usb_dev_state *ps, void __user *arg) if (copy_from_user(&data, arg, sizeof(data))) return -EFAULT; - /* This is an one way operation. Once privileges are + /* This is a one way operation. Once privileges are * dropped, you cannot regain them. You may however reissue * this ioctl to shrink the allowed interfaces mask. */ diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index 6bde4396927c..a2615d64d07c 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1848,7 +1848,7 @@ dev_config (struct file *fd, const char __user *buf, size_t len, loff_t *ptr) fail: spin_unlock_irq (&dev->lock); - pr_debug ("%s: %s fail %Zd, %p\n", shortname, __func__, value, dev); + pr_debug ("%s: %s fail %zd, %p\n", shortname, __func__, value, dev); kfree (dev->buf); dev->buf = NULL; return value; diff --git a/drivers/usb/gadget/udc/fsl_udc_core.c b/drivers/usb/gadget/udc/fsl_udc_core.c index 2e41ef36b944..b76fcdb763a0 100644 --- a/drivers/usb/gadget/udc/fsl_udc_core.c +++ b/drivers/usb/gadget/udc/fsl_udc_core.c @@ -520,7 +520,7 @@ static void struct_ep_qh_setup(struct fsl_udc *udc, unsigned char ep_num, /* Setup qh structure and ep register for ep0. */ static void ep0_setup(struct fsl_udc *udc) { - /* the intialization of an ep includes: fields in QH, Regs, + /* the initialization of an ep includes: fields in QH, Regs, * fsl_ep struct */ struct_ep_qh_setup(udc, 0, USB_RECV, USB_ENDPOINT_XFER_CONTROL, USB_MAX_CTRL_PAYLOAD, 0, 0); @@ -2349,7 +2349,7 @@ static int struct_ep_setup(struct fsl_udc *udc, unsigned char index, } /* Driver probe function - * all intialization operations implemented here except enabling usb_intr reg + * all initialization operations implemented here except enabling usb_intr reg * board setup should have been done in the platform code */ static int fsl_udc_probe(struct platform_device *pdev) diff --git a/drivers/usb/gadget/udc/renesas_usb3.c b/drivers/usb/gadget/udc/renesas_usb3.c index fb8fc34827ab..2218f91e92a6 100644 --- a/drivers/usb/gadget/udc/renesas_usb3.c +++ b/drivers/usb/gadget/udc/renesas_usb3.c @@ -1791,7 +1791,7 @@ static int renesas_usb3_init_ep(struct renesas_usb3 *usb3, struct device *dev, dev_dbg(dev, "%s: num_usb3_eps = %d\n", __func__, usb3->num_usb3_eps); /* - * This driver prepares pipes as the followings: + * This driver prepares pipes as follows: * - odd pipes = IN pipe * - even pipes = OUT pipe (except pipe 0) */ @@ -1841,7 +1841,7 @@ static void renesas_usb3_init_ram(struct renesas_usb3 *usb3, struct device *dev, memset(basead, 0, sizeof(basead)); /* - * This driver prepares pipes as the followings: + * This driver prepares pipes as follows: * - all pipes = the same size as "ramsize_per_pipe" * Please refer to the "Method of Specifying RAM Mapping" */ diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 063064801ceb..ac2c4eab478d 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -1322,7 +1322,7 @@ static int __init ehci_hcd_init(void) printk(KERN_WARNING "Warning! ehci_hcd should always be loaded" " before uhci_hcd and ohci_hcd, not after\n"); - pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n", + pr_debug("%s: block sizes: qh %zd qtd %zd itd %zd sitd %zd\n", hcd_name, sizeof(struct ehci_qh), sizeof(struct ehci_qtd), sizeof(struct ehci_itd), sizeof(struct ehci_sitd)); diff --git a/drivers/usb/host/fotg210-hcd.c b/drivers/usb/host/fotg210-hcd.c index 9d0b0518290a..1c5b34b74860 100644 --- a/drivers/usb/host/fotg210-hcd.c +++ b/drivers/usb/host/fotg210-hcd.c @@ -5697,7 +5697,7 @@ static int __init fotg210_hcd_init(void) test_bit(USB_OHCI_LOADED, &usb_hcds_loaded)) pr_warn("Warning! fotg210_hcd should always be loaded before uhci_hcd and ohci_hcd, not after\n"); - pr_debug("%s: block sizes: qh %Zd qtd %Zd itd %Zd\n", + pr_debug("%s: block sizes: qh %zd qtd %zd itd %zd\n", hcd_name, sizeof(struct fotg210_qh), sizeof(struct fotg210_qtd), sizeof(struct fotg210_itd)); diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c index 8685cf3e6292..b6daf2e69989 100644 --- a/drivers/usb/host/ohci-hcd.c +++ b/drivers/usb/host/ohci-hcd.c @@ -1252,7 +1252,7 @@ static int __init ohci_hcd_mod_init(void) return -ENODEV; printk(KERN_INFO "%s: " DRIVER_DESC "\n", hcd_name); - pr_debug ("%s: block sizes: ed %Zd td %Zd\n", hcd_name, + pr_debug ("%s: block sizes: ed %zd td %zd\n", hcd_name, sizeof (struct ed), sizeof (struct td)); set_bit(USB_OHCI_LOADED, &usb_hcds_loaded); diff --git a/drivers/usb/misc/adutux.c b/drivers/usb/misc/adutux.c index a540e4f206c4..c5fa584d8f0a 100644 --- a/drivers/usb/misc/adutux.c +++ b/drivers/usb/misc/adutux.c @@ -563,20 +563,20 @@ static ssize_t adu_write(struct file *file, const __user char *buffer, } dev_dbg(&dev->udev->dev, - "%s : in progress, count = %Zd\n", + "%s : in progress, count = %zd\n", __func__, count); } else { spin_unlock_irqrestore(&dev->buflock, flags); set_current_state(TASK_RUNNING); remove_wait_queue(&dev->write_wait, &waita); - dev_dbg(&dev->udev->dev, "%s : sending, count = %Zd\n", + dev_dbg(&dev->udev->dev, "%s : sending, count = %zd\n", __func__, count); /* write the data into interrupt_out_buffer from userspace */ buffer_size = usb_endpoint_maxp(dev->interrupt_out_endpoint); bytes_to_write = count > buffer_size ? buffer_size : count; dev_dbg(&dev->udev->dev, - "%s : buffer_size = %Zd, count = %Zd, bytes_to_write = %Zd\n", + "%s : buffer_size = %zd, count = %zd, bytes_to_write = %zd\n", __func__, buffer_size, count, bytes_to_write); if (copy_from_user(dev->interrupt_out_buffer, buffer, bytes_to_write) != 0) { diff --git a/drivers/usb/misc/legousbtower.c b/drivers/usb/misc/legousbtower.c index b10e26c74a90..322a042d6e59 100644 --- a/drivers/usb/misc/legousbtower.c +++ b/drivers/usb/misc/legousbtower.c @@ -673,7 +673,7 @@ static ssize_t tower_write (struct file *file, const char __user *buffer, size_t /* write the data into interrupt_out_buffer from userspace */ bytes_to_write = min_t(int, count, write_buffer_size); - dev_dbg(&dev->udev->dev, "%s: count = %Zd, bytes_to_write = %Zd\n", + dev_dbg(&dev->udev->dev, "%s: count = %zd, bytes_to_write = %zd\n", __func__, count, bytes_to_write); if (copy_from_user (dev->interrupt_out_buffer, buffer, bytes_to_write)) { diff --git a/drivers/usb/misc/uss720.c b/drivers/usb/misc/uss720.c index 356d312add57..0a643fa74cab 100644 --- a/drivers/usb/misc/uss720.c +++ b/drivers/usb/misc/uss720.c @@ -526,7 +526,7 @@ static size_t parport_uss720_epp_write_data(struct parport *pp, const void *buf, return 0; i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buf, length, &rlen, 20000); if (i) - printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buf, length, rlen); + printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %zu rlen %u\n", buf, length, rlen); change_mode(pp, ECR_PS2); return rlen; #endif @@ -587,7 +587,7 @@ static size_t parport_uss720_ecp_write_data(struct parport *pp, const void *buff return 0; i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, 20000); if (i) - printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buffer, len, rlen); + printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %zu rlen %u\n", buffer, len, rlen); change_mode(pp, ECR_PS2); return rlen; } @@ -605,7 +605,7 @@ static size_t parport_uss720_ecp_read_data(struct parport *pp, void *buffer, siz return 0; i = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), buffer, len, &rlen, 20000); if (i) - printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %Zu rlen %u\n", buffer, len, rlen); + printk(KERN_ERR "uss720: recvbulk ep 2 buf %p len %zu rlen %u\n", buffer, len, rlen); change_mode(pp, ECR_PS2); return rlen; } @@ -638,7 +638,7 @@ static size_t parport_uss720_write_compat(struct parport *pp, const void *buffer return 0; i = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), (void *)buffer, len, &rlen, 20000); if (i) - printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %Zu rlen %u\n", buffer, len, rlen); + printk(KERN_ERR "uss720: sendbulk ep 1 buf %p len %zu rlen %u\n", buffer, len, rlen); change_mode(pp, ECR_PS2); return rlen; } diff --git a/drivers/usb/usbip/usbip_common.c b/drivers/usb/usbip/usbip_common.c index 8b232290be6b..1a6f78d7d027 100644 --- a/drivers/usb/usbip/usbip_common.c +++ b/drivers/usb/usbip/usbip_common.c @@ -707,7 +707,7 @@ void usbip_pad_iso(struct usbip_device *ud, struct urb *urb) return; /* - * loop over all packets from last to first (to prevent overwritting + * loop over all packets from last to first (to prevent overwriting * memory when padding) and move them into the proper place */ for (i = np-1; i > 0; i--) { diff --git a/drivers/video/fbdev/aty/radeon_monitor.c b/drivers/video/fbdev/aty/radeon_monitor.c index 278b421ab3fe..dd823f5fe4c9 100644 --- a/drivers/video/fbdev/aty/radeon_monitor.c +++ b/drivers/video/fbdev/aty/radeon_monitor.c @@ -646,7 +646,7 @@ void radeon_probe_screens(struct radeonfb_info *rinfo, /* - * This functions applyes any arch/model/machine specific fixups + * This function applies any arch/model/machine specific fixups * to the panel info. It may eventually alter EDID block as * well or whatever is specific to a given model and not probed * properly by the default code diff --git a/drivers/video/fbdev/metronomefb.c b/drivers/video/fbdev/metronomefb.c index abb6bbf226d5..9085e9525341 100644 --- a/drivers/video/fbdev/metronomefb.c +++ b/drivers/video/fbdev/metronomefb.c @@ -187,7 +187,7 @@ static int load_waveform(u8 *mem, size_t size, int m, int t, epd_frame_table[par->dt].wfm_size = user_wfm_size; if (size != epd_frame_table[par->dt].wfm_size) { - dev_err(dev, "Error: unexpected size %Zd != %d\n", size, + dev_err(dev, "Error: unexpected size %zd != %d\n", size, epd_frame_table[par->dt].wfm_size); return -EINVAL; } diff --git a/drivers/watchdog/bcm2835_wdt.c b/drivers/watchdog/bcm2835_wdt.c index 496f6c106bb1..b339e0e67b4c 100644 --- a/drivers/watchdog/bcm2835_wdt.c +++ b/drivers/watchdog/bcm2835_wdt.c @@ -36,9 +36,9 @@ #define PM_RSTC_RESET 0x00000102 /* - * The Raspberry Pi firmware uses the RSTS register to know which partiton - * to boot from. The partiton value is spread into bits 0, 2, 4, 6, 8, 10. - * Partiton 63 is a special partition used by the firmware to indicate halt. + * The Raspberry Pi firmware uses the RSTS register to know which partition + * to boot from. The partition value is spread into bits 0, 2, 4, 6, 8, 10. + * Partition 63 is a special partition used by the firmware to indicate halt. */ #define PM_RSTS_RASPBERRYPI_HALT 0x555 |