ACPI patch candidates for 2.6.24 merge window
Subsystems (5)
Len Brown
reviewerLen Brown
reviewerPATCH 1/37 sony-laptop: old Vaio models contain 2 IO port entries
From: Mattia Dongili <[email protected]>
Make the driver aware of this case and manage the existence of a second separate IO port.
--- drivers/misc/sony-laptop.c | 204 ++++++++++++++++++++++++++++++++------------ 1 files changed, 148 insertions(+), 56 deletions(-)
drivers/misc/sony-laptop.c +148 -56
@@ -1173,7 +1173,8 @@ static struct acpi_driver sony_nc_driver = {#define SONYPI_TYPE3_OFFSET 0x12struct sony_pic_ioport { -struct acpi_resource_io io; +struct acpi_resource_io io1; +struct acpi_resource_io io2;struct list_head list; };
@@ -1443,11 +1444,11 @@ static u8 sony_pic_call1(u8 dev) {u8 v1, v2; -wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 , +wait_on_command (inb_p (spic_dev.cur_ioport->io1.minimum +4 ) &2 ,ITERATIONS_LONG ); -outb (dev, spic_dev.cur_ioport->io.minimum +4 ); - v1 =inb_p (spic_dev.cur_ioport->io.minimum +4 ); - v2 =inb_p (spic_dev.cur_ioport->io.minimum); +outb (dev, spic_dev.cur_ioport->io1.minimum +4 ); + v1 =inb_p (spic_dev.cur_ioport->io1.minimum +4 ); + v2 =inb_p (spic_dev.cur_ioport->io1.minimum);dprintk ("sony_pic_call1: 0x%.4x\n" , (v2 <<8 ) | v1);return v2; }
@@ -1456,13 +1457,13 @@ static u8 sony_pic_call2(u8 dev, u8 fn) {u8 v1; -wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 , +wait_on_command (inb_p (spic_dev.cur_ioport->io1.minimum +4 ) &2 ,ITERATIONS_LONG ); -outb (dev, spic_dev.cur_ioport->io.minimum +4 ); -wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 , +outb (dev, spic_dev.cur_ioport->io1.minimum +4 ); +wait_on_command (inb_p (spic_dev.cur_ioport->io1.minimum +4 ) &2 ,ITERATIONS_LONG ); -outb (fn, spic_dev.cur_ioport->io.minimum); - v1 =inb_p (spic_dev.cur_ioport->io.minimum); +outb (fn, spic_dev.cur_ioport->io1.minimum); + v1 =inb_p (spic_dev.cur_ioport->io1.minimum);dprintk ("sony_pic_call2: 0x%.4x\n" , v1);return v1; }
@@ -1471,13 +1472,13 @@ static u8 sony_pic_call3(u8 dev, u8 fn, u8 v) {u8 v1; -wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 ,ITERATIONS_LONG ); -outb (dev, spic_dev.cur_ioport->io.minimum +4 ); -wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 ,ITERATIONS_LONG ); -outb (fn, spic_dev.cur_ioport->io.minimum); -wait_on_command (inb_p (spic_dev.cur_ioport->io.minimum +4 ) &2 ,ITERATIONS_LONG ); -outb (v, spic_dev.cur_ioport->io.minimum); - v1 =inb_p (spic_dev.cur_ioport->io.minimum); +wait_on_command (inb_p (spic_dev.cur_ioport->io1.minimum +4 ) &2 ,ITERATIONS_LONG ); +outb (dev, spic_dev.cur_ioport->io1.minimum +4 ); +wait_on_command (inb_p (spic_dev.cur_ioport->io1.minimum +4 ) &2 ,ITERATIONS_LONG ); +outb (fn, spic_dev.cur_ioport->io1.minimum); +wait_on_command (inb_p (spic_dev.cur_ioport->io1.minimum +4 ) &2 ,ITERATIONS_LONG ); +outb (v, spic_dev.cur_ioport->io1.minimum); + v1 =inb_p (spic_dev.cur_ioport->io1.minimum);dprintk ("sony_pic_call3: 0x%.4x\n" , v1);return v1; }
@@ -2074,7 +2075,18 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)switch (resource->type) {case ACPI_RESOURCE_TYPE_START_DEPENDENT : + { +/* start IO enumeration */ +struct sony_pic_ioport *ioport =kzalloc (sizeof (*ioport),GFP_KERNEL ); +if (!ioport) +return AE_ERROR ; + +list_add (&ioport->list, &dev->ioports); +return AE_OK ; + } +case ACPI_RESOURCE_TYPE_END_DEPENDENT : +/* end IO enumeration */ return AE_OK ;case ACPI_RESOURCE_TYPE_IRQ :
@@ -2101,7 +2113,7 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)if (!interrupt)return AE_ERROR ; -list_add_tail (&interrupt->list, &dev->interrupts); +list_add (&interrupt->list, &dev->interrupts); interrupt->irq.triggering = p->triggering; interrupt->irq.polarity = p->polarity; interrupt->irq.sharable = p->sharable;
@@ -2113,18 +2125,27 @@ sony_pic_read_possible_resource(struct acpi_resource *resource, void *context)case ACPI_RESOURCE_TYPE_IO : {struct acpi_resource_io *io = &resource->data.io; -struct sony_pic_ioport *ioport =NULL ; +struct sony_pic_ioport *ioport = + list_first_entry(&dev->ioports, struct sony_pic_ioport, list);if (!io) {dprintk ("Blank IO resource\n" );return AE_OK ; } - ioport =kzalloc (sizeof (*ioport),GFP_KERNEL ); -if (!ioport) +if (!ioport->io1.minimum) { +memcpy (&ioport->io1, io,sizeof (*io)); +dprintk ("IO1 at 0x%.4x (0x%.2x)\n" , ioport->io1.minimum, + ioport->io1.address_length); + } +else if (!ioport->io2.minimum) { +memcpy (&ioport->io2, io,sizeof (*io)); +dprintk ("IO2 at 0x%.4x (0x%.2x)\n" , ioport->io2.minimum, + ioport->io2.address_length); + } +else { + printk(KERN_ERR DRV_PFX "Unknown SPIC Type, more than 2 IO Ports\n");return AE_ERROR ; - -list_add_tail (&ioport->list, &dev->ioports); -memcpy (&ioport->io, io,sizeof (*io)); + }return AE_OK ; }default :
@@ -2199,10 +2220,22 @@ static int sony_pic_enable(struct acpi_device *device, {acpi_status status;int result =0 ; +/* Type 1 resource layout is: +* IO +* IO +* IRQNoFlags +* End +* +* Type 2 and 3 resource layout is: +* IO +* IRQNoFlags +* End +*/ struct { -struct acpi_resource io_res; -struct acpi_resource irq_res; -struct acpi_resource end; +struct acpi_resource res1; +struct acpi_resource res2; +struct acpi_resource res3; +struct acpi_resource res4; } *resource;struct acpi_buffer buffer = {0 ,NULL };
@@ -2217,21 +2250,49 @@ static int sony_pic_enable(struct acpi_device *device, buffer.length =sizeof (*resource) +1 ; buffer.pointer = resource; -/* setup io resource */ - resource->io_res.type =ACPI_RESOURCE_TYPE_IO ; - resource->io_res.length =sizeof (struct acpi_resource ); -memcpy (&resource->io_res.data.io, &ioport->io, -sizeof (struct acpi_resource_io )); +/* setup Type 1 resources */ +if (spic_dev.model ==SONYPI_DEVICE_TYPE1 ) { -/* setup irq resource */ - resource->irq_res.type =ACPI_RESOURCE_TYPE_IRQ ; - resource->irq_res.length =sizeof (struct acpi_resource ); -memcpy (&resource->irq_res.data.irq, &irq->irq, -sizeof (struct acpi_resource_irq )); -/* we requested a shared irq */ - resource->irq_res.data.irq.sharable =ACPI_SHARED ; +/* setup io resources */ + resource->res1.type =ACPI_RESOURCE_TYPE_IO ; + resource->res1.length =sizeof (struct acpi_resource ); +memcpy (&resource->res1.data.io, &ioport->io1, +sizeof (struct acpi_resource_io )); - resource->end.type =ACPI_RESOURCE_TYPE_END_TAG ; + resource->res2.type =ACPI_RESOURCE_TYPE_IO ; + resource->res2.length =sizeof (struct acpi_resource ); +memcpy (&resource->res2.data.io, &ioport->io2, +sizeof (struct acpi_resource_io )); + +/* setup irq resource */ + resource->res3.type =ACPI_RESOURCE_TYPE_IRQ ; + resource->res3.length =sizeof (struct acpi_resource ); +memcpy (&resource->res3.data.irq, &irq->irq, +sizeof (struct acpi_resource_irq )); +/* we requested a shared irq */ + resource->res3.data.irq.sharable =ACPI_SHARED ; + + resource->res4.type =ACPI_RESOURCE_TYPE_END_TAG ; + + } +/* setup Type 2/3 resources */ +else { +/* setup io resource */ + resource->res1.type =ACPI_RESOURCE_TYPE_IO ; + resource->res1.length =sizeof (struct acpi_resource ); +memcpy (&resource->res1.data.io, &ioport->io1, +sizeof (struct acpi_resource_io )); + +/* setup irq resource */ + resource->res2.type =ACPI_RESOURCE_TYPE_IRQ ; + resource->res2.length =sizeof (struct acpi_resource ); +memcpy (&resource->res2.data.irq, &irq->irq, +sizeof (struct acpi_resource_irq )); +/* we requested a shared irq */ + resource->res2.data.irq.sharable =ACPI_SHARED ; + + resource->res3.type =ACPI_RESOURCE_TYPE_END_TAG ; + }/* Attempt to set the resource */ dprintk ("Evaluating _SRS\n" );
@@ -2239,7 +2300,7 @@ static int sony_pic_enable(struct acpi_device *device,/* check for total failure */ if (ACPI_FAILURE (status)) { - printk(KERN_ERR DRV_PFX "Error evaluating _SRS"); + printk(KERN_ERR DRV_PFX "Error evaluating _SRS\n"); result = -ENODEV ; goto end; }
@@ -2268,11 +2329,14 @@ static irqreturn_t sony_pic_irq(int irq, void *dev_id)struct sony_pic_dev *dev = (struct sony_pic_dev *) dev_id; - ev =inb_p (dev->cur_ioport->io.minimum); - data_mask =inb_p (dev->cur_ioport->io.minimum + dev->evport_offset); + ev =inb_p (dev->cur_ioport->io1.minimum); +if (dev->cur_ioport->io2.minimum) + data_mask =inb_p (dev->cur_ioport->io2.minimum); +else + data_mask =inb_p (dev->cur_ioport->io1.minimum + dev->evport_offset);dprintk ("event ([%.2x] [%.2x]) at port 0x%.4x(+0x%.2x)\n" , - ev, data_mask, dev->cur_ioport->io.minimum, dev->evport_offset); + ev, data_mask, dev->cur_ioport->io1.minimum, dev->evport_offset);if (ev ==0x00 || ev ==0xff )return IRQ_HANDLED ;
@@ -2323,8 +2387,11 @@ static int sony_pic_remove(struct acpi_device *device, int type) }free_irq (spic_dev.cur_irq->irq.interrupts[0 ], &spic_dev); -release_region (spic_dev.cur_ioport->io.minimum, - spic_dev.cur_ioport->io.address_length); +release_region (spic_dev.cur_ioport->io1.minimum, + spic_dev.cur_ioport->io1.address_length); +if (spic_dev.cur_ioport->io2.minimum) +release_region (spic_dev.cur_ioport->io2.minimum, + spic_dev.cur_ioport->io2.address_length);sonypi_compat_exit ();
@@ -2397,14 +2464,36 @@ static int sony_pic_add(struct acpi_device *device) goto err_remove_input;/* request io port */ -list_for_each_entry (io, &spic_dev.ioports, list) { -if (request_region (io->io.minimum, io->io.address_length, +list_for_each_entry_reverse (io, &spic_dev.ioports, list) { +if (request_region (io->io1.minimum, io->io1.address_length,"Sony Programable I/O Device" )) { -dprintk ("I/O port: 0x%.4x (0x%.4x) + 0x%.2x\n" , - io->io.minimum, io->io.maximum, - io->io.address_length); - spic_dev.cur_ioport = io; -break ; +dprintk ("I/O port1: 0x%.4x (0x%.4x) + 0x%.2x\n" , + io->io1.minimum, io->io1.maximum, + io->io1.address_length); +/* Type 1 have 2 ioports */ +if (io->io2.minimum) { +if (request_region (io->io2.minimum, + io->io2.address_length, +"Sony Programable I/O Device" )) { +dprintk ("I/O port2: 0x%.4x (0x%.4x) + 0x%.2x\n" , + io->io2.minimum, io->io2.maximum, + io->io2.address_length); + spic_dev.cur_ioport = io; +break ; + } +else { +dprintk ("Unable to get I/O port2: " +"0x%.4x (0x%.4x) + 0x%.2x\n" , + io->io2.minimum, io->io2.maximum, + io->io2.address_length); +release_region (io->io1.minimum, + io->io1.address_length); + } + } +else { + spic_dev.cur_ioport = io; +break ; + } } }if (!spic_dev.cur_ioport) {
@@ -2414,7 +2503,7 @@ static int sony_pic_add(struct acpi_device *device) }/* request IRQ */ -list_for_each_entry (irq, &spic_dev.interrupts, list) { +list_for_each_entry_reverse (irq, &spic_dev.interrupts, list) {if (!request_irq (irq->irq.interrupts[0 ], sony_pic_irq,IRQF_SHARED ,"sony-laptop" , &spic_dev)) { dprintk("IRQ: %d - triggering: %d - "
@@ -2462,8 +2551,11 @@ err_free_irq:free_irq (spic_dev.cur_irq->irq.interrupts[0 ], &spic_dev); err_release_region: -release_region (spic_dev.cur_ioport->io.minimum, - spic_dev.cur_ioport->io.address_length); +release_region (spic_dev.cur_ioport->io1.minimum, + spic_dev.cur_ioport->io1.address_length); +if (spic_dev.cur_ioport->io2.minimum) +release_region (spic_dev.cur_ioport->io2.minimum, + spic_dev.cur_ioport->io2.address_length); err_remove_compat:sonypi_compat_exit ();
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 2/37 fujitsu-laptop: create Fujitsu laptop platform specific driver
In reply to Len BrownFrom: Jonathan Woithe <[email protected]>
--- drivers/misc/Kconfig | 15 ++ drivers/misc/Makefile | 1 + drivers/misc/fujitsu-laptop.c | 358 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 374 insertions(+), 0 deletions(-) create mode 100644 drivers/misc/fujitsu-laptop.c
drivers/misc/Kconfig +15 -0
@@ -111,6 +111,21 @@ config ASUS_LAPTOP If you have an ACPI-compatible ASUS laptop, say Y or M here. +config FUJITSU_LAPTOP + tristate "Fujitsu Laptop Extras" + depends on X86 + depends on ACPI + depends on BACKLIGHT_CLASS_DEVICE + ---help--- + This is a driver for laptops built by Fujitsu: + + * P2xxx/P5xxx/S6xxx/S7xxx series Lifebooks + * Possibly other Fujitsu laptop models + + It adds support for LCD brightness control. + + If you have a Fujitsu laptop, say Y or M here. + config MSI_LAPTOP tristate "MSI Laptop Extras" depends on X86
drivers/misc/Makefile +1 -0
@@ -14,4 +14,5 @@ obj-$(CONFIG_PHANTOM) += phantom.o obj-$(CONFIG_SGI_IOC4) += ioc4.o obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o obj-$(CONFIG_THINKPAD_ACPI) += thinkpad_acpi.o +obj-$(CONFIG_FUJITSU_LAPTOP) += fujitsu-laptop.o obj-$(CONFIG_EEPROM_93CX6) += eeprom_93cx6.o
drivers/misc/fujitsu-laptop.c new file +358 -0
358 lines not on this page · raw message
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 3/37 ACPI: thermal: use round_jiffies when thermal zone polling is enabled
In reply to Len BrownFrom: Len Brown <[email protected]>
Properly functioning systems do not use thermal zone polling, they use event-based notification.
However, some users enable periodic thermal zone polling to work around bugs on their platforms, and at least one platform exists with a real _TZP that requests polling.
While thermal zone polling (_TZP) is specified in units to 0.1 seconds, it actually has a maximum granularity of 1 second. Thus, we can safely round up the _TZP timeout to occur on the next 1-second boundary. This will batch it with other 1-second-granularity timers in the system and thus potentially extend processor idle duration.
Note that the same timer is used both for _TZP
and for passive processor thermal throttling.
We can not round up the timeout when it is used
for passive thermal throttling.
Also, we can not make this a deferrable timer,
as temperature is just as relevant during idle
as it is during non-idle.
--- drivers/acpi/thermal.c | 13 ++++++++----- 1 files changed, 8 insertions(+), 5 deletions(-)
drivers/acpi/thermal.c +8 -5
@@ -711,6 +711,7 @@ static void acpi_thermal_check(void *data)int result =0 ;struct acpi_thermal *tz = data;unsigned long sleep_time =0 ; +unsigned long timeout_jiffies =0 ;int i =0 ;struct acpi_thermal_state state;
@@ -787,10 +788,13 @@ static void acpi_thermal_check(void *data)* a thermal event occurs). Note that _TSP and _TZD values are * given in 1/10th seconds (we must covert to milliseconds). */ -if (tz->state.passive) +if (tz->state.passive) { sleep_time = tz->trips.passive.tsp *100 ; -else if (tz->polling_frequency >0 ) + timeout_jiffies = jiffies + (HZ * sleep_time) /1000 ; + }else if (tz->polling_frequency >0 ) { sleep_time = tz->polling_frequency *100 ; + timeout_jiffies =round_jiffies (jiffies + (HZ * sleep_time) /1000 ); + }ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"%s: temperature[%lu] sleep[%lu]\n" , tz->name, tz->temperature, sleep_time));
@@ -804,12 +808,11 @@ static void acpi_thermal_check(void *data)del_timer (&(tz->timer)); }else {if (timer_pending (&(tz->timer))) -mod_timer (&(tz->timer), - jiffies + (HZ * sleep_time) /1000 ); +mod_timer (&(tz->timer), timeout_jiffies);else { tz->timer.data = (unsigned long )tz; tz->timer.function = acpi_thermal_run; - tz->timer.expires = jiffies + (HZ * sleep_time) /1000 ; + tz->timer.expires = timeout_jiffies;add_timer (&(tz->timer)); } }
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 4/37 ACPI: Thermal: Drop concurrent thermal checks
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Fix for #3686, where get_temperature() may cause thermal notify, which causes one more get_temperature().
--- drivers/acpi/thermal.c | 15 ++++++++++----- 1 files changed, 10 insertions(+), 5 deletions(-)
drivers/acpi/thermal.c +10 -5
@@ -195,6 +195,7 @@ struct acpi_thermal {struct acpi_thermal_trips trips;struct acpi_handle_list devices;struct timer_list timer; +struct mutex lock; };static const struct file_operations acpi_thermal_state_fops = {
@@ -721,11 +722,15 @@ static void acpi_thermal_check(void *data)return ; } +/* Check if someone else is already running */ +if (!mutex_trylock (&tz->lock)) +return ; + state = tz->state; result =acpi_thermal_get_temperature (tz);if (result) -return ; + goto unlock;memset (&tz->state,0 ,sizeof (tz->state));
@@ -816,8 +821,8 @@ static void acpi_thermal_check(void *data)add_timer (&(tz->timer)); } } - -return ; + unlock: +mutex_unlock (&tz->lock); }/* --------------------------------------------------------------------------
@@ -1254,7 +1259,7 @@ static int acpi_thermal_add(struct acpi_device *device)strcpy (acpi_device_name (device),ACPI_THERMAL_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_THERMAL_CLASS );acpi_driver_data (device) = tz; - +mutex_init (&tz->lock); result =acpi_thermal_get_info (tz);if (result) goto end;
@@ -1324,7 +1329,7 @@ static int acpi_thermal_remove(struct acpi_device *device, int type) }acpi_thermal_remove_fs (device); - +mutex_destroy (&tz->lock);kfree (tz);return 0 ; }
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 5/37 ACPI: video: Don't call absent methods
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/video.c | 18 ++++++++++-------- 1 files changed, 10 insertions(+), 8 deletions(-)
drivers/acpi/video.c +10 -8
@@ -409,14 +409,16 @@ acpi_video_device_lcd_query_levels(struct acpi_video_device *device,static int acpi_video_device_lcd_set_level (struct acpi_video_device *device,int level) { -int status; +int status =AE_OK ;union acpi_object arg0 = {ACPI_TYPE_INTEGER };struct acpi_object_list args = {1 , &arg0 }; arg0.integer.value = level; - status =acpi_evaluate_object (device->dev->handle,"_BCM" , &args,NULL ); - +if (device->cap._BCM) + status =acpi_evaluate_object (device->dev->handle,"_BCM" , + &args,NULL ); + device->brightness->curr = level;printk (KERN_DEBUG "set_level status: %x\n" , status);return status; }
@@ -425,11 +427,11 @@ static int acpi_video_device_lcd_get_level_current(struct acpi_video_device *device, unsigned long *level) { - int status; - - status =acpi_evaluate_integer (device->dev->handle,"_BQC" ,NULL , level); - -return status; + if (device->cap._BQC) + return acpi_evaluate_integer(device->dev->handle, "_BQC", NULL, + level); + *level = device->brightness->curr; +return AE_OK ; } static int
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 6/37 ACPI: VIDEO: Adjust current level to closest available one.
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/video.c | 13 ++++++++++++- 1 files changed, 12 insertions(+), 1 deletions(-)
drivers/acpi/video.c +12 -1
@@ -1636,9 +1636,20 @@ static int acpi_video_get_next_level(struct acpi_video_device *device, u32 level_current, u32 event) { - int min, max, min_above, max_below, i, l; + int min, max, min_above, max_below, i, l, delta = 255; max = max_below =0 ; min = min_above =255 ; +/* Find closest level to level_current */ +for (i =0 ; i < device->brightness->count; i++) { + l = device->brightness->levels[i]; +if (abs (l - level_current) <abs (delta)) { + delta = l - level_current; +if (!delta) +break ; + } + } +/* Ajust level_current to closest available level */ + level_current += delta;for (i =0 ; i < device->brightness->count; i++) { l = device->brightness->levels[i];if (l < min)
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 7/37 ACPI: EC: Drop ECDT-based boot_ec as soon as we find DSDT-based one.
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
ASUS notebooks have numerous problems with EC initialization This patch tries to work around three known issues reported in bugzilla 8598, 8709 and 8909/8919.
--- drivers/acpi/ec.c | 90 +++++++++++++++++++++++------------------------------ 1 files changed, 39 insertions(+), 51 deletions(-)
drivers/acpi/ec.c +39 -51
@@ -121,6 +121,7 @@ static struct acpi_ec {atomic_t event_count;wait_queue_head_t wait;struct list_head list; +u8 handlers_installed; } *boot_ec, *first_ec;/* --------------------------------------------------------------------------
@@ -680,32 +681,50 @@ ec_parse_device(acpi_handle handle, u32 Level, void *context, void **retval) status =acpi_evaluate_integer (handle,"_GPE" ,NULL , &ec->gpe);if (ACPI_FAILURE (status))return status; -/* Find and register all query methods */ acpi_walk_namespace (ACPI_TYPE_METHOD , handle,1 , acpi_ec_register_query_methods, ec,NULL ); -/* Use the global lock for all EC transactions? */ acpi_evaluate_integer (handle,"_GLK" ,NULL , &ec->global_lock); - ec->handle = handle; - - printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", - ec->gpe, ec->command_addr, ec->data_addr); -return AE_CTRL_TERMINATE ; } +static void ec_remove_handlers (struct acpi_ec *ec) +{ +if (ACPI_FAILURE (acpi_remove_address_space_handler (ec->handle, +ACPI_ADR_SPACE_EC , &acpi_ec_space_handler))) + printk(KERN_ERR PREFIX "failed to remove space handler\n"); +if (ACPI_FAILURE (acpi_remove_gpe_handler (NULL , ec->gpe, + &acpi_ec_gpe_handler))) + printk(KERN_ERR PREFIX "failed to remove gpe handler\n"); + ec->handlers_installed =0 ; +} +static int acpi_ec_add (struct acpi_device *device) {struct acpi_ec *ec =NULL ;if (!device)return -EINVAL ; -strcpy (acpi_device_name (device),ACPI_EC_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_EC_CLASS ); +/* Check for boot EC */ +if (boot_ec) { +if (boot_ec->handle == device->handle) { +/* Pre-loaded EC from DSDT, just move pointer */ + ec = boot_ec; + boot_ec =NULL ; + goto end; + }else if (boot_ec->handle ==ACPI_ROOT_OBJECT ) { +/* ECDT-based EC, time to shut it down */ +ec_remove_handlers (boot_ec); +kfree (boot_ec); + first_ec = boot_ec =NULL ; + } + } + ec =make_acpi_ec ();if (!ec)return -ENOMEM ;
@@ -715,25 +734,14 @@ static int acpi_ec_add(struct acpi_device *device)kfree (ec);return -EINVAL ; } - -/* Check if we found the boot EC */ -if (boot_ec) { -if (boot_ec->gpe == ec->gpe) { -/* We might have incorrect info for GL at boot time */ -mutex_lock (&boot_ec->lock); - boot_ec->global_lock = ec->global_lock; -/* Copy handlers from new ec into boot ec */ -list_splice (&ec->list, &boot_ec->list); -mutex_unlock (&boot_ec->lock); -kfree (ec); - ec = boot_ec; - } - }else - first_ec = ec; ec->handle = device->handle; + end: +if (!first_ec) + first_ec = ec;acpi_driver_data (device) = ec; -acpi_ec_add_fs (device); + printk(KERN_INFO PREFIX "GPE = 0x%lx, I/O: command/status = 0x%lx, data = 0x%lx\n", + ec->gpe, ec->command_addr, ec->data_addr);return 0 ; }
@@ -756,10 +764,7 @@ static int acpi_ec_remove(struct acpi_device *device, int type)acpi_driver_data (device) =NULL ;if (ec == first_ec) first_ec =NULL ; - -/* Don't touch boot EC */ -if (boot_ec != ec) -kfree (ec); +kfree (ec);return 0 ; }
@@ -789,6 +794,8 @@ ec_parse_io_ports(struct acpi_resource *resource, void *context)static int ec_install_handlers (struct acpi_ec *ec) {acpi_status status; +if (ec->handlers_installed) +return 0 ; status =acpi_install_gpe_handler (NULL , ec->gpe,ACPI_GPE_EDGE_TRIGGERED , &acpi_ec_gpe_handler, ec);
@@ -807,6 +814,7 @@ static int ec_install_handlers(struct acpi_ec *ec)return -ENODEV ; } + ec->handlers_installed =1 ;return 0 ; }
@@ -823,41 +831,22 @@ static int acpi_ec_start(struct acpi_device *device)if (!ec)return -EINVAL ; -/* Boot EC is already working */ -if (ec != boot_ec) - ret =ec_install_handlers (ec); + ret =ec_install_handlers (ec);/* EC is fully operational, allow queries */ atomic_set (&ec->query_pending,0 ); -return ret; }static int acpi_ec_stop (struct acpi_device *device,int type) { -acpi_status status;struct acpi_ec *ec; -if (!device)return -EINVAL ; - ec =acpi_driver_data (device);if (!ec)return -EINVAL ; - -/* Don't touch boot EC */ -if (ec == boot_ec) -return 0 ; - - status =acpi_remove_address_space_handler (ec->handle, -ACPI_ADR_SPACE_EC , - &acpi_ec_space_handler); -if (ACPI_FAILURE (status)) -return -ENODEV ; - - status =acpi_remove_gpe_handler (NULL , ec->gpe, &acpi_ec_gpe_handler); -if (ACPI_FAILURE (status)) -return -ENODEV ; +ec_remove_handlers (ec);return 0 ; }
@@ -877,7 +866,7 @@ int __init acpi_ec_ecdt_probe(void) status =acpi_get_table (ACPI_SIG_ECDT ,1 , (struct acpi_table_header **)&ecdt_ptr);if (ACPI_SUCCESS (status)) { - printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n\n"); + printk(KERN_INFO PREFIX "EC description table is found, configuring boot EC\n"); boot_ec->command_addr = ecdt_ptr->control.address; boot_ec->data_addr = ecdt_ptr->data.address; boot_ec->gpe = ecdt_ptr->gpe;
@@ -899,7 +888,6 @@ int __init acpi_ec_ecdt_probe(void) error:kfree (boot_ec); boot_ec =NULL ; -return -ENODEV ; }
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 8/37 sony-laptop/thinkpad-acpi: fix INPUT=n build
In reply to Len BrownFrom: Andreas Herrmann <[email protected]>
Build errors if CONFIG_SONY_LAPTOP && !INPUT or if CONFIG_THINKPAD_ACPI && !INPUT:
LD vmlinux
...
drivers/built-in.o: In function `sony_laptop_remove_input':
sony-laptop.c:(.text+0x768fb): undefined reference to `input_unregister_device'
...
drivers/built-in.o: In function `thinkpad_acpi_module_exit':
thinkpad_acpi.c:(.text+0x78c1b): undefined reference to `input_free_device'
...--- drivers/misc/Kconfig | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/misc/Kconfig +2 -0
@@ -134,6 +134,7 @@ config SONY_LAPTOP tristate "Sony Laptop Extras" depends on X86 && ACPI select BACKLIGHT_CLASS_DEVICE + depends on INPUT ---help--- This mini-driver drives the SNC and SPIC devices present in the ACPI BIOS of the Sony Vaio laptops.
@@ -156,6 +157,7 @@ config THINKPAD_ACPI select BACKLIGHT_CLASS_DEVICE select HWMON select NVRAM + depends on INPUT ---help--- This is a driver for the IBM and Lenovo ThinkPad laptops. It adds support for Fn-Fx key combinations, Bluetooth control, video
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 9/37 acpi_video: kernel build error if !INPUT
In reply to Len BrownFrom: Andreas Herrmann <[email protected]>
Commit e9dab1960ac9746fa34eff726b81635147615a79
(ACPI video hotkey: export missing ACPI video hotkey events via input layer) exports ACPI video hotkey events via input layer. But this breaks kernel build if ACPI_VIDEO && !INPUT:
LD .tmp_vmlinux1drivers/built-in.o: In function `acpi_video_bus_remove':drivers/acpi/video.c:2007: undefined reference to `input_unregister_device'
...
--- drivers/acpi/Kconfig | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
drivers/acpi/Kconfig +1 -0
@@ -117,6 +117,7 @@ config ACPI_BUTTON config ACPI_VIDEO tristate "Video" depends on X86 && BACKLIGHT_CLASS_DEVICE && VIDEO_OUTPUT_CONTROL + depends on INPUT help This driver implement the ACPI Extensions For Display Adapters for integrated graphics devices on motherboard, as specified in
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 10/37 ACPI: thinkpad-acpi: make room for more features in tp_features bitfield
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Increase tp_features to 32 bits. It is too close to running out of room.
--- drivers/misc/thinkpad_acpi.h | 30 +++++++++++++++--------------- 1 files changed, 15 insertions(+), 15 deletions(-)
drivers/misc/thinkpad_acpi.h +15 -15
@@ -233,22 +233,22 @@ struct ibm_init_struct {static struct {#ifdef CONFIG_THINKPAD_ACPI_BAY -u16 bay_status:1 ; -u16 bay_eject:1 ; -u16 bay_status2:1 ; -u16 bay_eject2:1 ; +u32 bay_status:1 ; +u32 bay_eject:1 ; +u32 bay_status2:1 ; +u32 bay_eject2:1 ;#endif -u16 bluetooth:1 ; -u16 hotkey:1 ; -u16 hotkey_mask:1 ; -u16 hotkey_wlsw:1 ; -u16 light:1 ; -u16 light_status:1 ; -u16 wan:1 ; -u16 fan_ctrl_status_undef:1 ; -u16 input_device_registered:1 ; -u16 platform_drv_registered:1 ; -u16 platform_drv_attrs_registered:1 ; +u32 bluetooth:1 ; +u32 hotkey:1 ; +u32 hotkey_mask:1 ; +u32 hotkey_wlsw:1 ; +u32 light:1 ; +u32 light_status:1 ; +u32 wan:1 ; +u32 fan_ctrl_status_undef:1 ; +u32 input_device_registered:1 ; +u32 platform_drv_registered:1 ; +u32 platform_drv_attrs_registered:1 ; } tp_features;struct thinkpad_id_data {
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 11/37 ACPI: thinkpad-acpi: issue EV_SYNC after EV_SWITCH
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
We were missing a input_sync on the radio switch event report path. Add it.
--- drivers/misc/thinkpad_acpi.c | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
drivers/misc/thinkpad_acpi.c +3 -1
@@ -1149,9 +1149,11 @@ static void tpacpi_input_send_radiosw(void) {int wlsw; -if (tp_features.hotkey_wlsw && !hotkey_get_wlsw (&wlsw)) +if (tp_features.hotkey_wlsw && !hotkey_get_wlsw (&wlsw)) {input_report_switch (tpacpi_inputdev,SW_RADIO , !!wlsw); +input_sync (tpacpi_inputdev); + } }static void hotkey_notify (struct ibm_struct *ibm,u32 event)
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 12/37 ACPI: thinkpad-acpi: add mutex-based locking to input device event send path
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Protect the input device event sending path with a mutex, since hot key input events are not atomic and require an cohesive event block to be sent together.
--- drivers/misc/thinkpad_acpi.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-)
drivers/misc/thinkpad_acpi.c +10 -0
@@ -519,6 +519,7 @@ static char *next_cmd(char **cmds)static struct platform_device *tpacpi_pdev;static struct class_device *tpacpi_hwmon;static struct input_dev *tpacpi_inputdev; +static struct mutex tpacpi_inputdev_send_mutex;static int tpacpi_resume_handler (struct platform_device *pdev)
@@ -1131,6 +1132,8 @@ static void tpacpi_input_send_key(unsigned int scancode, unsigned int keycode) {if (keycode !=KEY_RESERVED ) { +mutex_lock (&tpacpi_inputdev_send_mutex); +input_report_key (tpacpi_inputdev, keycode,1 );if (keycode ==KEY_UNKNOWN ) input_event(tpacpi_inputdev, EV_MSC, MSC_SCAN,
@@ -1142,6 +1145,8 @@ static void tpacpi_input_send_key(unsigned int scancode,input_event (tpacpi_inputdev,EV_MSC ,MSC_SCAN , scancode);input_sync (tpacpi_inputdev); + +mutex_unlock (&tpacpi_inputdev_send_mutex); } }
@@ -1149,11 +1154,15 @@ static void tpacpi_input_send_radiosw(void) {int wlsw; +mutex_lock (&tpacpi_inputdev_send_mutex); +if (tp_features.hotkey_wlsw && !hotkey_get_wlsw (&wlsw)) {input_report_switch (tpacpi_inputdev,SW_RADIO , !!wlsw);input_sync (tpacpi_inputdev); } + +mutex_unlock (&tpacpi_inputdev_send_mutex); }static void hotkey_notify (struct ibm_struct *ibm,u32 event)
@@ -4737,6 +4746,7 @@ static int __init thinkpad_acpi_module_init(void)thinkpad_acpi_module_exit ();return ret; } +mutex_init (&tpacpi_inputdev_send_mutex); tpacpi_inputdev =input_allocate_device ();if (!tpacpi_inputdev) {printk (IBM_ERR "unable to allocate input device\n" );
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 13/37 ACPI: thinkpad-acpi: keep track of module state
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Keep track of module state (init, running, exit). This makes it trivially easy to avoid running any interrupt handlers, threads, or any other async activity before we are ready, or when we want to go away.
--- drivers/misc/thinkpad_acpi.c | 20 +++++++++++++++++++- 1 files changed, 19 insertions(+), 1 deletions(-)
drivers/misc/thinkpad_acpi.c +19 -1
@@ -117,6 +117,12 @@ IBM_BIOS_MODULE_ALIAS("K[U,X-Z]");#define __unused __attribute__ ((unused)) +static enum { +TPACPI_LIFE_INIT =0 , +TPACPI_LIFE_RUNNING , +TPACPI_LIFE_EXITING , +} tpacpi_lifecycle; +/**************************************************************************** **************************************************************************** *
@@ -342,6 +348,9 @@ static void dispatch_acpi_notify(acpi_handle handle, u32 event, void *data) {struct ibm_struct *ibm = data; +if (tpacpi_lifecycle !=TPACPI_LIFE_RUNNING ) +return ; +if (!ibm || !ibm->acpi || !ibm->acpi->notify)return ;
@@ -3899,6 +3908,9 @@ static void fan_watchdog_fire(struct work_struct *ignored) {int rc; +if (tpacpi_lifecycle !=TPACPI_LIFE_RUNNING ) +return ; +printk (IBM_NOTICE "fan watchdog: enabling fan\n" ); rc =fan_set_enable ();if (rc <0 ) {
@@ -3919,7 +3931,8 @@ static void fan_watchdog_reset(void)if (fan_watchdog_active)cancel_delayed_work (&fan_watchdog_task); - if (fan_watchdog_maxinterval > 0) { + if (fan_watchdog_maxinterval > 0 && + tpacpi_lifecycle != TPACPI_LIFE_EXITING) { fan_watchdog_active = 1; if (!schedule_delayed_work(&fan_watchdog_task, msecs_to_jiffies(fan_watchdog_maxinterval
@@ -4685,6 +4698,8 @@ static int __init thinkpad_acpi_module_init(void) {int ret, i; + tpacpi_lifecycle =TPACPI_LIFE_INIT ; +/* Parameter checking */ if (hotkey_report_mode >2 )return -EINVAL ;
@@ -4781,6 +4796,7 @@ static int __init thinkpad_acpi_module_init(void) tp_features.input_device_registered =1 ; } + tpacpi_lifecycle =TPACPI_LIFE_RUNNING ;return 0 ; }
@@ -4788,6 +4804,8 @@ static void thinkpad_acpi_module_exit(void) {struct ibm_struct *ibm, *itmp; + tpacpi_lifecycle =TPACPI_LIFE_EXITING ; +list_for_each_entry_safe_reverse (ibm, itmp, &tpacpi_all_drivers, all_drivers) {
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 14/37 ACPI: thinkpad-acpi: check version of hot key firmware
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Check the HKEY firmware version (HKEY.MHKV handler), and refuse to load if it is unknown. Use this instead of the presence of HKEY.DHKV to detect hot key mask capability.
--- drivers/misc/thinkpad_acpi.c | 28 +++++++++++++++++++++++----- 1 files changed, 23 insertions(+), 5 deletions(-)
drivers/misc/thinkpad_acpi.c +23 -5
@@ -999,6 +999,7 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)int res, i;int status; +int hkeyv;vdbg_printk (TPACPI_DBG_INIT ,"initializing hotkey subdriver\n" );
@@ -1024,18 +1025,35 @@ static int __init hotkey_init(struct ibm_init_struct *iibm)return res;/* mask not supported on 570, 600e/x, 770e, 770x, A21e, A2xm/p, -A30, R30, R31, T20-22, X20-21, X22-24 */ - tp_features.hotkey_mask = -acpi_evalf (hkey_handle,NULL ,"DHKN" ,"qv" ); +A30, R30, R31, T20-22, X20-21, X22-24. Detected by checking +for HKEY interface version 0x100 */ +if (acpi_evalf (hkey_handle, &hkeyv,"MHKV" ,"qd" )) { +if ((hkeyv >>8 ) !=1 ) { +printk (IBM_ERR "unknown version of the " +"HKEY interface: 0x%x\n" , hkeyv); +printk (IBM_ERR "please report this to %s\n" , +IBM_MAIL ); + }else { +/* +* MHKV 0x100 in A31, R40, R40e, +* T4x, X31, and later +* */ + tp_features.hotkey_mask =1 ; + } + }vdbg_printk (TPACPI_DBG_INIT ,"hotkey masks are %s\n" ,str_supported (tp_features.hotkey_mask));if (tp_features.hotkey_mask) { -/* MHKA available in A31, R40, R40e, T4x, X31, and later */ if (!acpi_evalf (hkey_handle, &hotkey_all_mask, -"MHKA" ,"qd" )) +"MHKA" ,"qd" )) { +printk (IBM_ERR +"missing MHKA handler, " +"please report this to %s\n" , +IBM_MAIL ); hotkey_all_mask =0x080cU ;/* FN+F12, FN+F4, FN+F3 */ + } } res =hotkey_get (&hotkey_orig_status, &hotkey_orig_mask);
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 15/37 ACPI: thinkpad-acpi: dequeue all pending hot key events at once (v2.2)
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Receive all pending HKEY events at once from a single notification, and don't complain if the queue is empty.
--- drivers/misc/thinkpad_acpi.c | 51 ++++++++++++++++++++++++++++-------------- 1 files changed, 34 insertions(+), 17 deletions(-)
drivers/misc/thinkpad_acpi.c +34 -17
@@ -1196,9 +1196,30 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) {u32 hkey;unsigned int keycode, scancode; -int send_acpi_ev =0 ; +int send_acpi_ev; + +if (event !=0x80 ) { +printk (IBM_ERR "unknown HKEY notification event %d\n" , event); +/* forward it to userspace, maybe it knows how to handle it */ +acpi_bus_generate_netlink_event (ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event,0 ); +return ; + } + +while (1 ) { +if (!acpi_evalf (hkey_handle, &hkey,"MHKP" ,"d" )) { +printk (IBM_ERR "failed to retrieve HKEY event\n" ); +return ; + } + +if (hkey ==0 ) { +/* queue empty */ +return ; + } + + send_acpi_ev =0 ; -if (event ==0x80 &&acpi_evalf (hkey_handle, &hkey,"MHKP" ,"d" )) {switch (hkey >>12 ) {case 1 :/* 0x1000-0x1FFF: key presses */
@@ -1220,8 +1241,8 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)* eat up known LID events */ if (hkey !=0x5001 && hkey !=0x5002 ) {printk (IBM_ERR -"unknown LID-related hotkey event: 0x%04x\n" , - hkey); +"unknown LID-related HKEY event: 0x%04x\n" , + hkey); send_acpi_ev =1 ; }break ;
@@ -1240,21 +1261,17 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)printk (IBM_NOTICE "unhandled HKEY event 0x%04x\n" , hkey); send_acpi_ev =1 ; } - }else { -printk (IBM_ERR "unknown hotkey notification event %d\n" , event); - hkey =0 ; - send_acpi_ev =1 ; - } -/* Legacy events */ -if (send_acpi_ev || hotkey_report_mode <2 ) -acpi_bus_generate_proc_event (ibm->acpi->device, event, hkey); +/* Legacy events */ +if (send_acpi_ev || hotkey_report_mode <2 ) +acpi_bus_generate_proc_event (ibm->acpi->device, event, hkey); -/* netlink events */ -if (send_acpi_ev) { -acpi_bus_generate_netlink_event (ibm->acpi->device->pnp.device_class, - ibm->acpi->device->dev.bus_id, - event, hkey); +/* netlink events */ +if (send_acpi_ev) { +acpi_bus_generate_netlink_event (ibm->acpi->device->pnp.device_class, + ibm->acpi->device->dev.bus_id, + event, hkey); + } } }
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 16/37 ACPI: thinkpad-acpi: fix regression on HKEY LID event handling
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
We were letting ThinkPad-specific LID events through to userspace again, instead of dropping them. Fix it. We don't want to give userspace the option of not using generic LID handling.
--- drivers/misc/thinkpad_acpi.c | 9 +++++++-- 1 files changed, 7 insertions(+), 2 deletions(-)
drivers/misc/thinkpad_acpi.c +7 -2
@@ -1197,6 +1197,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)u32 hkey;unsigned int keycode, scancode;int send_acpi_ev; +int ignore_acpi_ev;if (event !=0x80 ) {printk (IBM_ERR "unknown HKEY notification event %d\n" , event);
@@ -1219,6 +1220,7 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) } send_acpi_ev =0 ; + ignore_acpi_ev =0 ;switch (hkey >>12 ) {case 1 :
@@ -1244,6 +1246,8 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event)"unknown LID-related HKEY event: 0x%04x\n" , hkey); send_acpi_ev =1 ; + }else { + ignore_acpi_ev =1 ; }break ;case 7 :
@@ -1263,11 +1267,12 @@ static void hotkey_notify(struct ibm_struct *ibm, u32 event) }/* Legacy events */ -if (send_acpi_ev || hotkey_report_mode <2 ) +if (!ignore_acpi_ev && (send_acpi_ev || hotkey_report_mode <2 )) {acpi_bus_generate_proc_event (ibm->acpi->device, event, hkey); + }/* netlink events */ -if (send_acpi_ev) { +if (!ignore_acpi_ev && send_acpi_ev) {acpi_bus_generate_netlink_event (ibm->acpi->device->pnp.device_class, ibm->acpi->device->dev.bus_id, event, hkey);
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 17/37 ACPI: thinkpad-acpi: use a separate platform device for hwmon and name it (v2)
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Use a separate platform device and driver ("thinkpad_hwmon") to attach hwmon attributes and class, and add a name attribute of "thinkpad" to it, which defines the hwmon device name for libsensors4.
This makes thinkpad-acpi compatible with libsensors4 from lm-sensors, and the platform driver and device split will make it much easier to separate hwmon functionality into its own module later on.
--- Documentation/thinkpad-acpi.txt | 25 +++++++++--- drivers/misc/thinkpad_acpi.c | 79 +++++++++++++++++++++++++++++++++------ drivers/misc/thinkpad_acpi.h | 6 ++- 3 files changed, 91 insertions(+), 19 deletions(-)
Documentation/thinkpad-acpi.txt +19 -6
@@ -105,10 +105,15 @@ The version of thinkpad-acpi's sysfs interface is exported by the driver as a driver attribute (see below). Sysfs driver attributes are on the driver's sysfs attribute space, -for 2.6.20 this is /sys/bus/platform/drivers/thinkpad_acpi/. +for 2.6.23 this is /sys/bus/platform/drivers/thinkpad_acpi/ and +/sys/bus/platform/drivers/thinkpad_hwmon/ -Sysfs device attributes are on the driver's sysfs attribute space, -for 2.6.20 this is /sys/devices/platform/thinkpad_acpi/. +Sysfs device attributes are on the thinkpad_acpi device sysfs attribute +space, for 2.6.23 this is /sys/devices/platform/thinkpad_acpi/. + +Sysfs device attributes for the sensors and fan are on the +thinkpad_hwmon device's sysfs attribute space, but you should locate it +looking for a hwmon device with the name attribute of "thinkpad". Driver version --------------
@@ -766,7 +771,7 @@ Temperature sensors ------------------- procfs: /proc/acpi/ibm/thermal -sysfs device attributes: (hwmon) temp*_input +sysfs device attributes: (hwmon "thinkpad") temp*_input Most ThinkPads include six or more separate temperature sensors but only expose the CPU temperature through the standard ACPI methods. This
@@ -989,7 +994,9 @@ Fan control and monitoring: fan speed, fan enable/disable --------------------------------------------------------- procfs: /proc/acpi/ibm/fan -sysfs device attributes: (hwmon) fan_input, pwm1, pwm1_enable +sysfs device attributes: (hwmon "thinkpad") fan1_input, pwm1, + pwm1_enable +sysfs hwmon driver attributes: fan_watchdog NOTE NOTE NOTE: fan control operations are disabled by default for safety reasons. To enable them, the module parameter "fan_control=1"
@@ -1131,7 +1138,7 @@ hwmon device attribute fan1_input: which can take up to two minutes. May return rubbish on older ThinkPads. -driver attribute fan_watchdog: +hwmon driver attribute fan_watchdog: Fan safety watchdog timer interval, in seconds. Minimum is 1 second, maximum is 120 seconds. 0 disables the watchdog.
@@ -1233,3 +1240,9 @@ Sysfs interface changelog: layer, the radio switch generates input event EV_RADIO, and the driver enables hot key handling by default in the firmware. + +0x020000: ABI fix: added a separate hwmon platform device and + driver, which must be located by name (thinkpad) + and the hwmon class for libsensors4 (lm-sensors 3) + compatibility. Moved all hwmon attributes to this + new platform device.
drivers/misc/thinkpad_acpi.c +67 -12
175 lines not on this page · raw message
drivers/misc/thinkpad_acpi.h +5 -1
@@ -58,13 +58,14 @@#define IBM_NAME "thinkpad"#define IBM_DESC "ThinkPad ACPI Extras" -#define IBM_FILE "thinkpad_acpi" +#define IBM_FILE IBM_NAME "_acpi"#define IBM_URL "http://ibm-acpi.sf.net/"#define IBM_MAIL "[email protected]"#define IBM_PROC_DIR "ibm"#define IBM_ACPI_EVENT_PREFIX "ibm"#define IBM_DRVR_NAME IBM_FILE +#define IBM_HWMON_DRVR_NAME IBM_NAME "_hwmon"#define IBM_LOG IBM_FILE ": "#define IBM_ERR KERN_ERR IBM_LOG
@@ -171,6 +172,7 @@ static int parse_strtoul(const char *buf, unsigned long max,/* Device model */ static struct platform_device *tpacpi_pdev; +static struct platform_device *tpacpi_sensors_pdev;static struct class_device *tpacpi_hwmon;static struct platform_driver tpacpi_pdriver;static struct input_dev *tpacpi_inputdev;
@@ -249,6 +251,8 @@ static struct { u32 input_device_registered:1; u32 platform_drv_registered:1; u32 platform_drv_attrs_registered:1; + u32 sensors_pdrv_registered:1; + u32 sensors_pdev_attrs_registered:1; } tp_features;struct thinkpad_id_data {
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 18/37 ACPI: thinkpad-acpi: duplicate driver attributes to new hwmon pdrv
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Thinkpad-acpi has some driver attributes (debug level, sysfs interface version, etc) that also belong to the new hwmon driver. Duplicate them there.
--- drivers/misc/thinkpad_acpi.c | 8 +++++++- drivers/misc/thinkpad_acpi.h | 1 + 2 files changed, 8 insertions(+), 1 deletions(-)
drivers/misc/thinkpad_acpi.c +7 -1
@@ -4803,12 +4803,16 @@ static int __init thinkpad_acpi_module_init(void) tp_features.sensors_pdrv_registered =1 ; ret =tpacpi_create_driver_attributes (&tpacpi_pdriver.driver); +if (!ret) { + tp_features.platform_drv_attrs_registered =1 ; + ret =tpacpi_create_driver_attributes (&tpacpi_hwmon_pdriver.driver); + }if (ret) {printk (IBM_ERR "unable to create sysfs driver attributes\n" );thinkpad_acpi_module_exit ();return ret; } - tp_features.platform_drv_attrs_registered =1 ; + tp_features.sensors_pdrv_attrs_registered =1 ;/* Device initialization */
@@ -4919,6 +4923,8 @@ static void thinkpad_acpi_module_exit(void)if (tpacpi_pdev)platform_device_unregister (tpacpi_pdev); +if (tp_features.sensors_pdrv_attrs_registered) +tpacpi_remove_driver_attributes (&tpacpi_hwmon_pdriver.driver);if (tp_features.platform_drv_attrs_registered)tpacpi_remove_driver_attributes (&tpacpi_pdriver.driver);
drivers/misc/thinkpad_acpi.h +1 -0
@@ -252,6 +252,7 @@ static struct { u32 platform_drv_registered:1; u32 platform_drv_attrs_registered:1; u32 sensors_pdrv_registered:1; + u32 sensors_pdrv_attrs_registered:1; u32 sensors_pdev_attrs_registered:1; } tp_features;
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 19/37 ACPI: Hibernate erroneously disabled Suspend wakeup devices
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
S4 suspend to disk will disable GPE's permanently because acpi_gpe_sleep_prepare() does not have a counterpart at resume time. Thus, those devices became unavailable for wakeup from subsequent S3 suspend-to-ram.
Here acpi_gpe_sleep_prepare() is removed, and upon suspend acpi_enable_wakeup_device() gets its functionality. Upon resume, acpi_disable_wakeup_device() restores the state.
https://bugzilla.novell.com/show_bug.cgi?id=292300
--- drivers/acpi/sleep/main.c | 1 - drivers/acpi/sleep/sleep.h | 1 - drivers/acpi/sleep/wakeup.c | 117 +++++++++++++++---------------------------- include/acpi/acpi_bus.h | 1 - 4 files changed, 40 insertions(+), 80 deletions(-)
drivers/acpi/sleep/main.c +0 -1
@@ -44,7 +44,6 @@ int acpi_sleep_prepare(u32 acpi_state)ACPI_FLUSH_CPU_CACHE ();acpi_enable_wakeup_device_prep (acpi_state);#endif -acpi_gpe_sleep_prepare (acpi_state);acpi_enter_sleep_state_prep (acpi_state);return 0 ; }
drivers/acpi/sleep/sleep.h +0 -1
@@ -5,6 +5,5 @@ extern int acpi_suspend (u32 state);extern void acpi_enable_wakeup_device_prep (u8 sleep_state);extern void acpi_enable_wakeup_device (u8 sleep_state);extern void acpi_disable_wakeup_device (u8 sleep_state); -extern void acpi_gpe_sleep_prepare (u32 sleep_state);extern int acpi_sleep_prepare (u32 acpi_state);
drivers/acpi/sleep/wakeup.c +40 -77
157 lines not on this page · raw message
include/acpi/acpi_bus.h +0 -1
@@ -264,7 +264,6 @@ struct acpi_device_wakeup_flags {struct acpi_device_wakeup_state {u8 enabled:1 ; -u8 active:1 ; };struct acpi_device_wakeup {
Signature · 1 line
1.5.3.4.206.g58ba4
Re: [PATCH 19/37] ACPI: Hibernate erroneously disabled Suspend wakeup devices
Quoted 8 lines · Len Brown
From: Alexey Starikovskiy <[email protected]>
S4 suspend to disk will disable GPE's permanently because
acpi_gpe_sleep_prepare()does not have a counterpart at resume time. Thus, those devices became unavailable for wakeup from subsequent S3 suspend-to-ram.
Quoted 5 lines
Here
acpi_gpe_sleep_prepare()is removed, and upon suspendacpi_enable_wakeup_device()gets its functionality. Upon resume,acpi_disable_wakeup_device()restores the state.
This patch apparently causes problems to appear on some Acer boxes:
https://bugzilla.novell.com/show_bug.cgi?id=299882
Greetings,
Rafael
Len Brown
reviewerPATCH 20/37 ACPI: Battery: don't use acpi_extract_package()
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
acpi_extract_package() creates more problems with memory management than it solves as helper for package handling.
--- drivers/acpi/battery.c | 359 +++++++++++++++++++----------------------------- 1 files changed, 139 insertions(+), 220 deletions(-)
drivers/acpi/battery.c +139 -220
@@ -36,9 +36,6 @@#define ACPI_BATTERY_VALUE_UNKNOWN 0xFFFFFFFF -#define ACPI_BATTERY_FORMAT_BIF "NNNNNNNNNSSSS" -#define ACPI_BATTERY_FORMAT_BST "NNNN" -#define ACPI_BATTERY_COMPONENT 0x00040000#define ACPI_BATTERY_CLASS "battery"#define ACPI_BATTERY_DEVICE_NAME "Battery"
@@ -90,61 +87,49 @@ static struct acpi_driver acpi_battery_driver = { }, }; -struct acpi_battery_state { -acpi_integer state; -acpi_integer present_rate; -acpi_integer remaining_capacity; -acpi_integer present_voltage; -}; - -struct acpi_battery_info { -acpi_integer power_unit; -acpi_integer design_capacity; -acpi_integer last_full_capacity; -acpi_integer battery_technology; -acpi_integer design_voltage; -acpi_integer design_capacity_warning; -acpi_integer design_capacity_low; -acpi_integer battery_capacity_granularity_1; -acpi_integer battery_capacity_granularity_2; -acpi_string model_number; -acpi_string serial_number; -acpi_string battery_type; -acpi_string oem_info; -}; - -enum acpi_battery_files { +enum acpi_battery_files {ACPI_BATTERY_INFO =0 ,ACPI_BATTERY_STATE ,ACPI_BATTERY_ALARM ,ACPI_BATTERY_NUMFILES , }; -struct acpi_battery_flags { -u8 battery_present_prev; -u8 alarm_present; -u8 init_update; -u8 update[ACPI_BATTERY_NUMFILES ]; -u8 power_unit; -}; -struct acpi_battery { -struct mutex mutex;struct acpi_device *device; -struct acpi_battery_flags flags; -struct acpi_buffer bif_data; -struct acpi_buffer bst_data; +struct mutex lock;unsigned long alarm;unsigned long update_time[ACPI_BATTERY_NUMFILES ]; +int state; +int present_rate; +int remaining_capacity; +int present_voltage; +int power_unit; +int design_capacity; +int last_full_capacity; +int technology; +int design_voltage; +int design_capacity_warning; +int design_capacity_low; +int capacity_granularity_1; +int capacity_granularity_2; +char model_number[32 ]; +char serial_number[32 ]; +char type[32 ]; +char oem_info[32 ]; +u8 present_prev; +u8 alarm_present; +u8 init_update; +u8 update[ACPI_BATTERY_NUMFILES ]; };inline int acpi_battery_present (struct acpi_battery *battery) {return battery->device->status.battery_present; } +inline char *acpi_battery_power_units (struct acpi_battery *battery) { -if (battery->flags.power_unit) +if (battery->power_unit)return ACPI_BATTERY_UNITS_AMPS ;else return ACPI_BATTERY_UNITS_WATTS ;
@@ -165,43 +150,63 @@ static void acpi_battery_check_result(struct acpi_battery *battery, int result)return ;if (result) { - battery->flags.init_update =1 ; + battery->init_update =1 ; } } -static int acpi_battery_extract_package (struct acpi_battery *battery, -union acpi_object *package, -struct acpi_buffer *format, -struct acpi_buffer *data, -char *package_name) -{ -acpi_status status =AE_OK ; -struct acpi_buffer data_null = {0 ,NULL }; +struct acpi_offsets { +size_t offset;/* offset inside struct acpi_sbs_battery */ +u8 mode;/* int or string? */ +}; - status =acpi_extract_package (package, format, &data_null); -if (status !=AE_BUFFER_OVERFLOW ) { -ACPI_EXCEPTION ((AE_INFO , status,"Extracting size %s" , - package_name)); -return -ENODEV ; - } +static struct acpi_offsets state_offsets[] = { + {offsetof(struct acpi_battery , state),0 }, + {offsetof(struct acpi_battery , present_rate),0 }, + {offsetof(struct acpi_battery , remaining_capacity),0 }, + {offsetof(struct acpi_battery , present_voltage),0 }, +}; -if (data_null.length != data->length) { -kfree (data->pointer); - data->pointer =kzalloc (data_null.length,GFP_KERNEL ); -if (!data->pointer) { -ACPI_EXCEPTION ((AE_INFO ,AE_NO_MEMORY ,"kzalloc()" )); -return -ENOMEM ; - } - data->length = data_null.length; - } +static struct acpi_offsets info_offsets[] = { + {offsetof(struct acpi_battery , power_unit),0 }, + {offsetof(struct acpi_battery , design_capacity),0 }, + {offsetof(struct acpi_battery , last_full_capacity),0 }, + {offsetof(struct acpi_battery , technology),0 }, + {offsetof(struct acpi_battery , design_voltage),0 }, + {offsetof(struct acpi_battery , design_capacity_warning),0 }, + {offsetof(struct acpi_battery , design_capacity_low),0 }, + {offsetof(struct acpi_battery , capacity_granularity_1),0 }, + {offsetof(struct acpi_battery , capacity_granularity_2),0 }, + {offsetof(struct acpi_battery , model_number),1 }, + {offsetof(struct acpi_battery , serial_number),1 }, + {offsetof(struct acpi_battery , type),1 }, + {offsetof(struct acpi_battery , oem_info),1 }, +}; - status =acpi_extract_package (package, format, data); -if (ACPI_FAILURE (status)) { -ACPI_EXCEPTION ((AE_INFO , status,"Extracting %s" , - package_name)); -return -ENODEV ; +static int extract_package (struct acpi_battery *battery, +union acpi_object *package, +struct acpi_offsets *offsets,int num) +{ +int i, *x; +union acpi_object *element; +if (package->type !=ACPI_TYPE_PACKAGE ) +return -EFAULT ; +for (i =0 ; i < num; ++i) { +if (package->package.count <= i) +return -EFAULT ; + element = &package->package.elements[i]; +if (offsets[i].mode) { +if (element->type !=ACPI_TYPE_STRING && + element->type !=ACPI_TYPE_BUFFER ) +return -EFAULT ; +strncpy ((u8 *)battery + offsets[i].offset, + element->string.pointer,32 ); + }else { +if (element->type !=ACPI_TYPE_INTEGER ) +return -EFAULT ; + x = (int *)((u8 *)battery + offsets[i].offset); + *x = element->integer.value; + } } -return 0 ; }
@@ -222,49 +227,21 @@ static int acpi_battery_get_info(struct acpi_battery *battery)int result =0 ;acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; -struct acpi_buffer format = {sizeof (ACPI_BATTERY_FORMAT_BIF ), -ACPI_BATTERY_FORMAT_BIF - }; -union acpi_object *package =NULL ; -struct acpi_buffer *data =NULL ; -struct acpi_battery_info *bif =NULL ; battery->update_time[ACPI_BATTERY_INFO ] =get_seconds (); -if (!acpi_battery_present (battery))return 0 ; - -/* Evaluate _BIF */ - - status = -acpi_evaluate_object (acpi_battery_handle (battery),"_BIF" ,NULL , - &buffer); +mutex_lock (&battery->lock); + status =acpi_evaluate_object (acpi_battery_handle (battery),"_BIF" , +NULL , &buffer); +mutex_unlock (&battery->lock);if (ACPI_FAILURE (status)) {ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _BIF" ));return -ENODEV ; } - - package = buffer.pointer; - - data = &battery->bif_data; - -/* Extract Package Data */ - - result = -acpi_battery_extract_package (battery, package, &format, data, -"_BIF" ); -if (result) - goto end; - - end: - + result =extract_package (battery, buffer.pointer, + info_offsets,ARRAY_SIZE (info_offsets));kfree (buffer.pointer); - -if (!result) { - bif = data->pointer; - battery->flags.power_unit = bif->power_unit; - } -return result; }
@@ -273,42 +250,24 @@ static int acpi_battery_get_state(struct acpi_battery *battery)int result =0 ;acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; -struct acpi_buffer format = {sizeof (ACPI_BATTERY_FORMAT_BST ), -ACPI_BATTERY_FORMAT_BST - }; -union acpi_object *package =NULL ; -struct acpi_buffer *data =NULL ; battery->update_time[ACPI_BATTERY_STATE ] =get_seconds ();if (!acpi_battery_present (battery))return 0 ; -/* Evaluate _BST */ +mutex_lock (&battery->lock); + status =acpi_evaluate_object (acpi_battery_handle (battery),"_BST" , +NULL , &buffer); +mutex_unlock (&battery->lock); - status = -acpi_evaluate_object (acpi_battery_handle (battery),"_BST" ,NULL , - &buffer);if (ACPI_FAILURE (status)) {ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _BST" ));return -ENODEV ; } - - package = buffer.pointer; - - data = &battery->bst_data; - -/* Extract Package Data */ - - result = -acpi_battery_extract_package (battery, package, &format, data, -"_BST" ); -if (result) - goto end; - - end: + result =extract_package (battery, buffer.pointer, + state_offsets,ARRAY_SIZE (state_offsets));kfree (buffer.pointer); -return result; }
@@ -331,14 +290,15 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,if (!acpi_battery_present (battery))return -ENODEV ; -if (!battery->flags.alarm_present) +if (!battery->alarm_present)return -ENODEV ; arg0.integer.value = alarm; - status = -acpi_evaluate_object (acpi_battery_handle (battery),"_BTP" , - &arg_list,NULL ); +mutex_lock (&battery->lock); + status =acpi_evaluate_object (acpi_battery_handle (battery),"_BTP" , + &arg_list,NULL ); +mutex_unlock (&battery->lock);if (ACPI_FAILURE (status))return -ENODEV ;
@@ -354,22 +314,21 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery)int result =0 ;acpi_status status =AE_OK ;acpi_handle handle =NULL ; -struct acpi_battery_info *bif = battery->bif_data.pointer;unsigned long alarm = battery->alarm;/* See if alarms are supported, and if so, set default */ status =acpi_get_handle (acpi_battery_handle (battery),"_BTP" , &handle);if (ACPI_SUCCESS (status)) { - battery->flags.alarm_present =1 ; -if (!alarm && bif) { - alarm = bif->design_capacity_warning; + battery->alarm_present =1 ; +if (!alarm) { + alarm = battery->design_capacity_warning; } result =acpi_battery_set_alarm (battery, alarm);if (result) goto end; }else { - battery->flags.alarm_present =0 ; + battery->alarm_present =0 ; } end:
@@ -385,7 +344,7 @@ static int acpi_battery_init_update(struct acpi_battery *battery)if (result)return result; - battery->flags.battery_present_prev =acpi_battery_present (battery); + battery->present_prev =acpi_battery_present (battery);if (acpi_battery_present (battery)) { result =acpi_battery_get_info (battery);
@@ -411,7 +370,7 @@ static int acpi_battery_update(struct acpi_battery *battery, update =1 ; } -if (battery->flags.init_update) { +if (battery->init_update) { result =acpi_battery_init_update (battery);if (result) goto end;
@@ -420,8 +379,8 @@ static int acpi_battery_update(struct acpi_battery *battery, result =acpi_battery_get_status (battery);if (result) goto end; -if ((!battery->flags.battery_present_prev &acpi_battery_present (battery)) - || (battery->flags.battery_present_prev & !acpi_battery_present (battery))) { +if ((!battery->present_prev &acpi_battery_present (battery)) + || (battery->present_prev & !acpi_battery_present (battery))) { result =acpi_battery_init_update (battery);if (result) goto end;
@@ -433,7 +392,7 @@ static int acpi_battery_update(struct acpi_battery *battery, end: - battery->flags.init_update = (result !=0 ); + battery->init_update = (result !=0 ); *update_result_ptr = update_result;
@@ -444,19 +403,19 @@ static void acpi_battery_notify_update(struct acpi_battery *battery) {acpi_battery_get_status (battery); -if (battery->flags.init_update) { +if (battery->init_update) {return ; } -if ((!battery->flags.battery_present_prev & +if ((!battery->present_prev &acpi_battery_present (battery)) || - (battery->flags.battery_present_prev & + (battery->present_prev & !acpi_battery_present (battery))) { - battery->flags.init_update =1 ; + battery->init_update =1 ; }else { - battery->flags.update[ACPI_BATTERY_INFO ] =1 ; - battery->flags.update[ACPI_BATTERY_STATE ] =1 ; - battery->flags.update[ACPI_BATTERY_ALARM ] =1 ; + battery->update[ACPI_BATTERY_INFO ] =1 ; + battery->update[ACPI_BATTERY_STATE ] =1 ; + battery->update[ACPI_BATTERY_ALARM ] =1 ; } }
@@ -469,7 +428,6 @@ static struct proc_dir_entry *acpi_battery_dir;static int acpi_battery_print_info (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -struct acpi_battery_info *bif =NULL ;char *units ="?" ;if (result)
@@ -482,30 +440,23 @@ static int acpi_battery_print_info(struct seq_file *seq, int result) goto end; } - bif = battery->bif_data.pointer; -if (!bif) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"BIF buffer is NULL" )); - result = -ENODEV ; - goto end; - } -/* Battery Units */ units =acpi_battery_power_units (battery); -if (bif->design_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->design_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design capacity: unknown\n" );else seq_printf (seq,"design capacity: %d %sh\n" , - (u32 ) bif->design_capacity, units); + (u32 ) battery->design_capacity, units); -if (bif->last_full_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->last_full_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"last full capacity: unknown\n" );else seq_printf (seq,"last full capacity: %d %sh\n" , - (u32 ) bif->last_full_capacity, units); + (u32 ) battery->last_full_capacity, units); -switch ((u32 ) bif->battery_technology) { +switch ((u32 ) battery->technology) {case 0 :seq_printf (seq,"battery technology: non-rechargeable\n" );break ;
@@ -517,23 +468,23 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)break ; } -if (bif->design_voltage ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->design_voltage ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design voltage: unknown\n" );else seq_printf (seq,"design voltage: %d mV\n" , - (u32 ) bif->design_voltage); + (u32 ) battery->design_voltage);seq_printf (seq,"design capacity warning: %d %sh\n" , - (u32 ) bif->design_capacity_warning, units); + (u32 ) battery->design_capacity_warning, units);seq_printf (seq,"design capacity low: %d %sh\n" , - (u32 ) bif->design_capacity_low, units); + (u32 ) battery->design_capacity_low, units);seq_printf (seq,"capacity granularity 1: %d %sh\n" , - (u32 ) bif->battery_capacity_granularity_1, units); + (u32 ) battery->capacity_granularity_1, units);seq_printf (seq,"capacity granularity 2: %d %sh\n" , - (u32 ) bif->battery_capacity_granularity_2, units); -seq_printf (seq,"model number: %s\n" , bif->model_number); -seq_printf (seq,"serial number: %s\n" , bif->serial_number); -seq_printf (seq,"battery type: %s\n" , bif->battery_type); -seq_printf (seq,"OEM info: %s\n" , bif->oem_info); + (u32 ) battery->capacity_granularity_2, units); +seq_printf (seq,"model number: %s\n" , battery->model_number); +seq_printf (seq,"serial number: %s\n" , battery->serial_number); +seq_printf (seq,"battery type: %s\n" , battery->type); +seq_printf (seq,"OEM info: %s\n" , battery->oem_info); end:
@@ -546,7 +497,6 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)static int acpi_battery_print_state (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -struct acpi_battery_state *bst =NULL ;char *units ="?" ;if (result)
@@ -559,50 +509,43 @@ static int acpi_battery_print_state(struct seq_file *seq, int result) goto end; } - bst = battery->bst_data.pointer; -if (!bst) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"BST buffer is NULL" )); - result = -ENODEV ; - goto end; - } -/* Battery Units */ units =acpi_battery_power_units (battery); -if (!(bst->state &0x04 )) +if (!(battery->state &0x04 ))seq_printf (seq,"capacity state: ok\n" );else seq_printf (seq,"capacity state: critical\n" ); -if ((bst->state &0x01 ) && (bst->state &0x02 )) { +if ((battery->state &0x01 ) && (battery->state &0x02 )) {seq_printf (seq,"charging state: charging/discharging\n" ); - }else if (bst->state &0x01 ) + }else if (battery->state &0x01 )seq_printf (seq,"charging state: discharging\n" ); -else if (bst->state &0x02 ) +else if (battery->state &0x02 )seq_printf (seq,"charging state: charging\n" );else {seq_printf (seq,"charging state: charged\n" ); } -if (bst->present_rate ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->present_rate ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present rate: unknown\n" );else seq_printf (seq,"present rate: %d %s\n" , - (u32 ) bst->present_rate, units); + (u32 ) battery->present_rate, units); -if (bst->remaining_capacity ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->remaining_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"remaining capacity: unknown\n" );else seq_printf (seq,"remaining capacity: %d %sh\n" , - (u32 ) bst->remaining_capacity, units); + (u32 ) battery->remaining_capacity, units); -if (bst->present_voltage ==ACPI_BATTERY_VALUE_UNKNOWN ) +if (battery->present_voltage ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present voltage: unknown\n" );else seq_printf (seq,"present voltage: %d mV\n" , - (u32 ) bst->present_voltage); + (u32 ) battery->present_voltage); end:
@@ -658,8 +601,6 @@ acpi_battery_write_alarm(struct file *file,if (!battery || (count >sizeof (alarm_string) -1 ))return -EINVAL ; -mutex_lock (&battery->mutex); - result =acpi_battery_update (battery,1 , &update_result);if (result) { result = -ENODEV ;
@@ -689,9 +630,6 @@ acpi_battery_write_alarm(struct file *file,if (!result) result = count; - -mutex_unlock (&battery->mutex); -return result; }
@@ -714,10 +652,8 @@ static int acpi_battery_read(int fid, struct seq_file *seq)int update_result =ACPI_BATTERY_NONE_UPDATE ;int update =0 ; -mutex_lock (&battery->mutex); - update = (get_seconds () - battery->update_time[fid] >= update_time); - update = (update | battery->flags.update[fid]); + update = (update | battery->update[fid]); result =acpi_battery_update (battery, update, &update_result);if (result)
@@ -732,8 +668,7 @@ static int acpi_battery_read(int fid, struct seq_file *seq) end: result = acpi_read_funcs[fid].acpi_battery_check_result (battery, result); - battery->flags.update[fid] = result; -mutex_unlock (&battery->mutex); + battery->update[fid] = result;return result; }
@@ -900,20 +835,16 @@ static int acpi_battery_add(struct acpi_device *device)if (!battery)return -ENOMEM ; -mutex_init (&battery->mutex); - -mutex_lock (&battery->mutex); - battery->device = device;strcpy (acpi_device_name (device),ACPI_BATTERY_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_BATTERY_CLASS );acpi_driver_data (device) = battery; - +mutex_init (&battery->lock); result =acpi_battery_get_status (battery);if (result) goto end; - battery->flags.init_update =1 ; + battery->init_update =1 ; result =acpi_battery_add_fs (device);if (result)
@@ -939,8 +870,6 @@ static int acpi_battery_add(struct acpi_device *device)kfree (battery); } -mutex_unlock (&battery->mutex); -return result; }
@@ -954,22 +883,12 @@ static int acpi_battery_remove(struct acpi_device *device, int type) battery =acpi_driver_data (device); -mutex_lock (&battery->mutex); - status =acpi_remove_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_battery_notify);acpi_battery_remove_fs (device); - -kfree (battery->bif_data.pointer); - -kfree (battery->bst_data.pointer); - -mutex_unlock (&battery->mutex); - -mutex_destroy (&battery->mutex); - +mutex_destroy (&battery->lock);kfree (battery);return 0 ;
@@ -985,7 +904,7 @@ static int acpi_battery_resume(struct acpi_device *device) battery = device->driver_data; - battery->flags.init_update =1 ; + battery->init_update =1 ;return 0 ; }
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 21/37 ACPI: Battery: simplify update scheme
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/battery.c | 280 ++++++++++-------------------------------------- 1 files changed, 57 insertions(+), 223 deletions(-)
drivers/acpi/battery.c +57 -223
@@ -27,6 +27,7 @@#include <linux/module.h> #include <linux/init.h> #include <linux/types.h> +#include <linux/jiffies.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <asm/uaccess.h>
@@ -41,27 +42,18 @@#define ACPI_BATTERY_DEVICE_NAME "Battery"#define ACPI_BATTERY_NOTIFY_STATUS 0x80#define ACPI_BATTERY_NOTIFY_INFO 0x81 -#define ACPI_BATTERY_UNITS_WATTS "mW" -#define ACPI_BATTERY_UNITS_AMPS "mA"#define _COMPONENT ACPI_BATTERY_COMPONENT -#define ACPI_BATTERY_UPDATE_TIME 0 - -#define ACPI_BATTERY_NONE_UPDATE 0 -#define ACPI_BATTERY_EASY_UPDATE 1 -#define ACPI_BATTERY_INIT_UPDATE 2 -ACPI_MODULE_NAME ("battery" );MODULE_AUTHOR ("Paul Diefenbaugh" );MODULE_DESCRIPTION ("ACPI Battery Driver" );MODULE_LICENSE ("GPL" ); -static unsigned int update_time =ACPI_BATTERY_UPDATE_TIME ; - -/* 0 - every time, > 0 - by update_time */ -module_param (update_time, uint,0644 ); +static unsigned int cache_time =1000 ; +module_param (cache_time, uint,0644 ); +MODULE_PARM_DESC (cache_time,"cache time in milliseconds" );extern struct proc_dir_entry *acpi_lock_battery_dir (void );extern void *acpi_unlock_battery_dir (struct proc_dir_entry *acpi_battery_dir);
@@ -95,15 +87,12 @@ enum acpi_battery_files { };struct acpi_battery { -struct acpi_device *device;struct mutex lock; -unsigned long alarm; -unsigned long update_time[ACPI_BATTERY_NUMFILES ]; -int state; +struct acpi_device *device; +unsigned long update_time;int present_rate;int remaining_capacity;int present_voltage; -int power_unit;int design_capacity;int last_full_capacity;int technology;
@@ -112,14 +101,14 @@ struct acpi_battery {int design_capacity_low;int capacity_granularity_1;int capacity_granularity_2; +int alarm;char model_number[32 ];char serial_number[32 ];char type[32 ];char oem_info[32 ]; -u8 present_prev; +int state; +int power_unit;u8 alarm_present; -u8 init_update; -u8 update[ACPI_BATTERY_NUMFILES ]; };inline int acpi_battery_present (struct acpi_battery *battery)
@@ -127,33 +116,15 @@ inline int acpi_battery_present(struct acpi_battery *battery)return battery->device->status.battery_present; } -inline char *acpi_battery_power_units (struct acpi_battery *battery) +inline char *acpi_battery_units (struct acpi_battery *battery) { -if (battery->power_unit) -return ACPI_BATTERY_UNITS_AMPS ; -else -return ACPI_BATTERY_UNITS_WATTS ; -} - -inline acpi_handle acpi_battery_handle (struct acpi_battery *battery) -{ -return battery->device->handle; +return (battery->power_unit)?"mA" :"mW" ; }/* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ -static void acpi_battery_check_result (struct acpi_battery *battery,int result) -{ -if (!battery) -return ; - -if (result) { - battery->init_update =1 ; - } -} -struct acpi_offsets {size_t offset;/* offset inside struct acpi_sbs_battery */ u8 mode;/* int or string? */
@@ -228,11 +199,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery)acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; - battery->update_time[ACPI_BATTERY_INFO ] =get_seconds ();if (!acpi_battery_present (battery))return 0 ;mutex_lock (&battery->lock); - status =acpi_evaluate_object (acpi_battery_handle (battery),"_BIF" , + status =acpi_evaluate_object (battery->device->handle,"_BIF" ,NULL , &buffer);mutex_unlock (&battery->lock);if (ACPI_FAILURE (status)) {
@@ -251,13 +221,16 @@ static int acpi_battery_get_state(struct acpi_battery *battery)acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL }; - battery->update_time[ACPI_BATTERY_STATE ] =get_seconds (); -if (!acpi_battery_present (battery))return 0 ; +if (battery->update_time && +time_before (jiffies, battery->update_time + +msecs_to_jiffies (cache_time))) +return 0 ; +mutex_lock (&battery->lock); - status =acpi_evaluate_object (acpi_battery_handle (battery),"_BST" , + status =acpi_evaluate_object (battery->device->handle,"_BST" ,NULL , &buffer);mutex_unlock (&battery->lock);
@@ -267,14 +240,13 @@ static int acpi_battery_get_state(struct acpi_battery *battery) } result =extract_package (battery, buffer.pointer, state_offsets,ARRAY_SIZE (state_offsets)); + battery->update_time = jiffies;kfree (buffer.pointer);return result; }static int acpi_battery_get_alarm (struct acpi_battery *battery) { - battery->update_time[ACPI_BATTERY_ALARM ] =get_seconds (); -return 0 ; }
@@ -285,8 +257,6 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,union acpi_object arg0 = {ACPI_TYPE_INTEGER };struct acpi_object_list arg_list = {1 , &arg0 }; - battery->update_time[ACPI_BATTERY_ALARM ] =get_seconds (); -if (!acpi_battery_present (battery))return -ENODEV ;
@@ -296,8 +266,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, arg0.integer.value = alarm;mutex_lock (&battery->lock); - status =acpi_evaluate_object (acpi_battery_handle (battery),"_BTP" , - &arg_list,NULL ); + status =acpi_evaluate_object (battery->device->handle,"_BTP" , + &arg_list,NULL );mutex_unlock (&battery->lock);if (ACPI_FAILURE (status))return -ENODEV ;
@@ -311,112 +281,36 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery,static int acpi_battery_init_alarm (struct acpi_battery *battery) { -int result =0 ;acpi_status status =AE_OK ;acpi_handle handle =NULL ; -unsigned long alarm = battery->alarm;/* See if alarms are supported, and if so, set default */ - - status =acpi_get_handle (acpi_battery_handle (battery),"_BTP" , &handle); -if (ACPI_SUCCESS (status)) { - battery->alarm_present =1 ; -if (!alarm) { - alarm = battery->design_capacity_warning; - } - result =acpi_battery_set_alarm (battery, alarm); -if (result) - goto end; - }else { + status =acpi_get_handle (battery->device->handle,"_BTP" , &handle); +if (ACPI_FAILURE (status)) { battery->alarm_present =0 ; +return 0 ; } - - end: - -return result; + battery->alarm_present =1 ; +if (!battery->alarm) + battery->alarm = battery->design_capacity_warning; +return acpi_battery_set_alarm (battery, battery->alarm); } -static int acpi_battery_init_update (struct acpi_battery *battery) +static int acpi_battery_update (struct acpi_battery *battery) { -int result =0 ; - - result =acpi_battery_get_status (battery); -if (result) +int saved_present =acpi_battery_present (battery); +int result =acpi_battery_get_status (battery); +if (result || !acpi_battery_present (battery))return result; - - battery->present_prev =acpi_battery_present (battery); - -if (acpi_battery_present (battery)) { +if (saved_present !=acpi_battery_present (battery) || + !battery->update_time) { + battery->update_time =0 ; result =acpi_battery_get_info (battery);if (result)return result; - result =acpi_battery_get_state (battery); -if (result) -return result; -acpi_battery_init_alarm (battery); } - -return result; -} - -static int acpi_battery_update (struct acpi_battery *battery, -int update,int *update_result_ptr) -{ -int result =0 ; -int update_result =ACPI_BATTERY_NONE_UPDATE ; - -if (!acpi_battery_present (battery)) { - update =1 ; - } - -if (battery->init_update) { - result =acpi_battery_init_update (battery); -if (result) - goto end; - update_result =ACPI_BATTERY_INIT_UPDATE ; - }else if (update) { - result =acpi_battery_get_status (battery); -if (result) - goto end; -if ((!battery->present_prev &acpi_battery_present (battery)) - || (battery->present_prev & !acpi_battery_present (battery))) { - result =acpi_battery_init_update (battery); -if (result) - goto end; - update_result =ACPI_BATTERY_INIT_UPDATE ; - }else { - update_result =ACPI_BATTERY_EASY_UPDATE ; - } - } - - end: - - battery->init_update = (result !=0 ); - - *update_result_ptr = update_result; - -return result; -} - -static void acpi_battery_notify_update (struct acpi_battery *battery) -{ -acpi_battery_get_status (battery); - -if (battery->init_update) { -return ; - } - -if ((!battery->present_prev & -acpi_battery_present (battery)) || - (battery->present_prev & - !acpi_battery_present (battery))) { - battery->init_update =1 ; - }else { - battery->update[ACPI_BATTERY_INFO ] =1 ; - battery->update[ACPI_BATTERY_STATE ] =1 ; - battery->update[ACPI_BATTERY_ALARM ] =1 ; - } +return acpi_battery_get_state (battery); }/* --------------------------------------------------------------------------
@@ -442,7 +336,7 @@ static int acpi_battery_print_info(struct seq_file *seq, int result)/* Battery Units */ - units =acpi_battery_power_units (battery); + units =acpi_battery_units (battery);if (battery->design_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design capacity: unknown\n" );
@@ -511,7 +405,7 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)/* Battery Units */ - units =acpi_battery_power_units (battery); + units =acpi_battery_units (battery);if (!(battery->state &0x04 ))seq_printf (seq,"capacity state: ok\n" );
@@ -571,13 +465,13 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)/* Battery Units */ - units =acpi_battery_power_units (battery); + units =acpi_battery_units (battery);seq_printf (seq,"alarm: " );if (!battery->alarm)seq_printf (seq,"unsupported\n" );else -seq_printf (seq,"%lu %sh\n" , battery->alarm, units); +seq_printf (seq,"%u %sh\n" , battery->alarm, units); end:
@@ -587,49 +481,35 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)return result; } -static ssize_t -acpi_battery_write_alarm (struct file *file, -const char __user * buffer, -size_t count,loff_t * ppos) +static ssize_t acpi_battery_write_alarm (struct file *file, +const char __user * buffer, +size_t count,loff_t * ppos) {int result =0 ;char alarm_string[12 ] = {'\0' };struct seq_file *m = file->private_data;struct acpi_battery *battery = m->private; -int update_result =ACPI_BATTERY_NONE_UPDATE ;if (!battery || (count >sizeof (alarm_string) -1 ))return -EINVAL ; - - result =acpi_battery_update (battery,1 , &update_result);if (result) { result = -ENODEV ; goto end; } -if (!acpi_battery_present (battery)) { result = -ENODEV ; goto end; } -if (copy_from_user (alarm_string, buffer, count)) { result = -EFAULT ; goto end; } - alarm_string[count] ='\0' ; - - result =acpi_battery_set_alarm (battery, -simple_strtoul (alarm_string,NULL ,0 )); -if (result) - goto end; - + battery->alarm =simple_strtol (alarm_string,NULL ,0 ); + result =acpi_battery_set_alarm (battery, battery->alarm); end: - -acpi_battery_check_result (battery, result); -if (!result) - result = count; +return count;return result; }
@@ -648,28 +528,8 @@ static struct acpi_read_mux {static int acpi_battery_read (int fid,struct seq_file *seq) {struct acpi_battery *battery = seq->private; -int result =0 ; -int update_result =ACPI_BATTERY_NONE_UPDATE ; -int update =0 ; - - update = (get_seconds () - battery->update_time[fid] >= update_time); - update = (update | battery->update[fid]); - - result =acpi_battery_update (battery, update, &update_result); -if (result) - goto end; - -if (update_result ==ACPI_BATTERY_EASY_UPDATE ) { - result = acpi_read_funcs[fid].get (battery); -if (result) - goto end; - } - - end: - result = acpi_read_funcs[fid].acpi_battery_check_result (battery, result); - battery->update[fid] = result; -return result; +int result =acpi_battery_update (battery); +return acpi_read_funcs[fid].static int acpi_battery_read_info (struct seq_file *seq,void *offset)
@@ -793,33 +653,16 @@ static int acpi_battery_remove_fs(struct acpi_device *device)static void acpi_battery_notify (acpi_handle handle,u32 event,void *data) {struct acpi_battery *battery = data; -struct acpi_device *device =NULL ; - +struct acpi_device *device;if (!battery)return ; - device = battery->device; - -switch (event) { -case ACPI_BATTERY_NOTIFY_STATUS : -case ACPI_BATTERY_NOTIFY_INFO : -case ACPI_NOTIFY_BUS_CHECK : -case ACPI_NOTIFY_DEVICE_CHECK : - device = battery->device; -acpi_battery_notify_update (battery); -acpi_bus_generate_proc_event (device, event, +acpi_battery_update (battery); +acpi_bus_generate_proc_event (device, event, +acpi_battery_present (battery)); +acpi_bus_generate_netlink_event (device->pnp.device_class, + device->dev.bus_id, event,acpi_battery_present (battery)); -acpi_bus_generate_netlink_event (device->pnp.device_class, - device->dev.bus_id, event, -acpi_battery_present (battery)); -break ; -default : -ACPI_DEBUG_PRINT ((ACPI_DB_INFO , -"Unsupported event [0x%x]\n" , event)); -break ; - } - -return ; }static int acpi_battery_add (struct acpi_device *device)
@@ -840,12 +683,7 @@ static int acpi_battery_add(struct acpi_device *device)strcpy (acpi_device_class (device),ACPI_BATTERY_CLASS );acpi_driver_data (device) = battery;mutex_init (&battery->lock); - result =acpi_battery_get_status (battery); -if (result) - goto end; - - battery->init_update =1 ; - +acpi_battery_update (battery); result =acpi_battery_add_fs (device);if (result) goto end;
@@ -898,14 +736,10 @@ static int acpi_battery_remove(struct acpi_device *device, int type)static int acpi_battery_resume (struct acpi_device *device) {struct acpi_battery *battery; -if (!device)return -EINVAL ; - - battery = device->driver_data; - - battery->init_update =1 ; - + battery =acpi_driver_data (device); + battery->update_time =0 ;return 0 ; }
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 22/37 ACPI: Battery: Misc clean-ups, no functional changes
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/battery.c | 342 ++++++++++++++++++------------------------------ 1 files changed, 125 insertions(+), 217 deletions(-)
drivers/acpi/battery.c +125 -217
@@ -1,6 +1,8 @@/* -* acpi_battery.c - ACPI Battery Driver ($Revision: 37 $) +* battery.c - ACPI Battery Driver (Revision: 2.0) * +* Copyright (C) 2007 Alexey Starikovskiy <[email protected]> +* Copyright (C) 2004-2007 Vladimir Lebedev <[email protected]> * Copyright (C) 2001, 2002 Andy Grover <[email protected]> * Copyright (C) 2001, 2002 Paul Diefenbaugh <[email protected]> *
@@ -48,6 +50,7 @@ACPI_MODULE_NAME ("battery" );MODULE_AUTHOR ("Paul Diefenbaugh" ); +MODULE_AUTHOR ("Alexey Starikovskiy <[email protected]>" );MODULE_DESCRIPTION ("ACPI Battery Driver" );MODULE_LICENSE ("GPL" );
@@ -58,31 +61,17 @@ MODULE_PARM_DESC(cache_time, "cache time in milliseconds");extern struct proc_dir_entry *acpi_lock_battery_dir (void );extern void *acpi_unlock_battery_dir (struct proc_dir_entry *acpi_battery_dir); -static int acpi_battery_add (struct acpi_device *device); -static int acpi_battery_remove (struct acpi_device *device,int type); -static int acpi_battery_resume (struct acpi_device *device); -static const struct acpi_device_id battery_device_ids[] = { {"PNP0C0A" ,0 }, {"" ,0 }, }; -MODULE_DEVICE_TABLE (acpi, battery_device_ids); -static struct acpi_driver acpi_battery_driver = { - .name ="battery" , - .class =ACPI_BATTERY_CLASS , - .ids = battery_device_ids, - .ops = { - .add = acpi_battery_add, - .resume = acpi_battery_resume, - .remove = acpi_battery_remove, - }, -}; +MODULE_DEVICE_TABLE (acpi, battery_device_ids);enum acpi_battery_files { -ACPI_BATTERY_INFO =0 , -ACPI_BATTERY_STATE , -ACPI_BATTERY_ALARM , + info_tag =0 , + state_tag, + alarm_tag,ACPI_BATTERY_NUMFILES , };
@@ -124,7 +113,6 @@ inline char *acpi_battery_units(struct acpi_battery *battery)/* -------------------------------------------------------------------------- Battery Management -------------------------------------------------------------------------- */ -struct acpi_offsets {size_t offset;/* offset inside struct acpi_sbs_battery */ u8 mode;/* int or string? */
@@ -183,19 +171,16 @@ static int extract_package(struct acpi_battery *battery,static int acpi_battery_get_status (struct acpi_battery *battery) { -int result =0 ; - - result =acpi_bus_get_status (battery->device); -if (result) { +if (acpi_bus_get_status (battery->device)) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"Evaluating _STA" ));return -ENODEV ; } -return result; +return 0 ; }static int acpi_battery_get_info (struct acpi_battery *battery) { -int result =0 ; +int result = -EFAULT ;acpi_status status =0 ;struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER ,NULL };
@@ -205,10 +190,12 @@ static int acpi_battery_get_info(struct acpi_battery *battery) status =acpi_evaluate_object (battery->device->handle,"_BIF" ,NULL , &buffer);mutex_unlock (&battery->lock); +if (ACPI_FAILURE (status)) {ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _BIF" ));return -ENODEV ; } + result =extract_package (battery, buffer.pointer, info_offsets,ARRAY_SIZE (info_offsets));kfree (buffer.pointer);
@@ -238,6 +225,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)ACPI_EXCEPTION ((AE_INFO , status,"Evaluating _BST" ));return -ENODEV ; } + result =extract_package (battery, buffer.pointer, state_offsets,ARRAY_SIZE (state_offsets)); battery->update_time = jiffies;
@@ -245,37 +233,26 @@ static int acpi_battery_get_state(struct acpi_battery *battery)return result; } -static int acpi_battery_get_alarm (struct acpi_battery *battery) -{ -return 0 ; -} - -static int acpi_battery_set_alarm (struct acpi_battery *battery, -unsigned long alarm) +static int acpi_battery_set_alarm (struct acpi_battery *battery) {acpi_status status =0 ; -union acpi_object arg0 = {ACPI_TYPE_INTEGER }; +union acpi_object arg0 = { .type =ACPI_TYPE_INTEGER };struct acpi_object_list arg_list = {1 , &arg0 }; -if (!acpi_battery_present (battery)) -return -ENODEV ; - -if (!battery->alarm_present) +if (!acpi_battery_present (battery)|| !battery->alarm_present)return -ENODEV ; - arg0.integer.value = alarm; + arg0.integer.value = battery->alarm;mutex_lock (&battery->lock); status =acpi_evaluate_object (battery->device->handle,"_BTP" , &arg_list,NULL );mutex_unlock (&battery->lock); +if (ACPI_FAILURE (status))return -ENODEV ; -ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Alarm set to %d\n" , (u32 ) alarm)); - - battery->alarm = alarm; - +ACPI_DEBUG_PRINT ((ACPI_DB_INFO ,"Alarm set to %d\n" , battery->alarm));return 0 ; }
@@ -293,7 +270,7 @@ static int acpi_battery_init_alarm(struct acpi_battery *battery) battery->alarm_present =1 ;if (!battery->alarm) battery->alarm = battery->design_capacity_warning; -return acpi_battery_set_alarm (battery, battery->alarm); +return acpi_battery_set_alarm (battery); }static int acpi_battery_update (struct acpi_battery *battery)
@@ -322,130 +299,101 @@ static struct proc_dir_entry *acpi_battery_dir;static int acpi_battery_print_info (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -char *units ="?" ;if (result) goto end; -if (acpi_battery_present (battery)) -seq_printf (seq,"present: yes\n" ); -else { -seq_printf (seq,"present: no\n" ); +seq_printf (seq,"present: %s\n" , +acpi_battery_present (battery)?"yes" :"no" ); +if (!acpi_battery_present (battery)) goto end; - } - -/* Battery Units */ - - units =acpi_battery_units (battery); -if (battery->design_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design capacity: unknown\n" );else seq_printf (seq,"design capacity: %d %sh\n" , - (u32 ) battery->design_capacity, units); + battery->design_capacity, +acpi_battery_units (battery));if (battery->last_full_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"last full capacity: unknown\n" );else seq_printf (seq,"last full capacity: %d %sh\n" , - (u32 ) battery->last_full_capacity, units); - -switch ((u32 ) battery->technology) { -case 0 : -seq_printf (seq,"battery technology: non-rechargeable\n" ); -break ; -case 1 : -seq_printf (seq,"battery technology: rechargeable\n" ); -break ; -default : -seq_printf (seq,"battery technology: unknown\n" ); -break ; - } + battery->last_full_capacity, +acpi_battery_units (battery)); + +seq_printf (seq,"battery technology: %srechargeable\n" , + (!battery->technology)?"non-" :"" );if (battery->design_voltage ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"design voltage: unknown\n" );else seq_printf (seq,"design voltage: %d mV\n" , - (u32 ) battery->design_voltage); + battery->design_voltage);seq_printf (seq,"design capacity warning: %d %sh\n" , - (u32 ) battery->design_capacity_warning, units); + battery->design_capacity_warning, +acpi_battery_units (battery));seq_printf (seq,"design capacity low: %d %sh\n" , - (u32 ) battery->design_capacity_low, units); + battery->design_capacity_low, +acpi_battery_units (battery));seq_printf (seq,"capacity granularity 1: %d %sh\n" , - (u32 ) battery->capacity_granularity_1, units); + battery->capacity_granularity_1, +acpi_battery_units (battery));seq_printf (seq,"capacity granularity 2: %d %sh\n" , - (u32 ) battery->capacity_granularity_2, units); + battery->capacity_granularity_2, +acpi_battery_units (battery));seq_printf (seq,"model number: %s\n" , battery->model_number);seq_printf (seq,"serial number: %s\n" , battery->serial_number);seq_printf (seq,"battery type: %s\n" , battery->type);seq_printf (seq,"OEM info: %s\n" , battery->oem_info); - end: -if (result)seq_printf (seq,"ERROR: Unable to read battery info\n" ); -return result; }static int acpi_battery_print_state (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -char *units ="?" ;if (result) goto end; -if (acpi_battery_present (battery)) -seq_printf (seq,"present: yes\n" ); -else { -seq_printf (seq,"present: no\n" ); +seq_printf (seq,"present: %s\n" , +acpi_battery_present (battery)?"yes" :"no" ); +if (!acpi_battery_present (battery)) goto end; - } - -/* Battery Units */ - - units =acpi_battery_units (battery); -if (!(battery->state &0x04 )) -seq_printf (seq,"capacity state: ok\n" ); -else -seq_printf (seq,"capacity state: critical\n" ); - -if ((battery->state &0x01 ) && (battery->state &0x02 )) { +seq_printf (seq,"capacity state: %s\n" , + (battery->state &0x04 )?"critical" :"ok" ); +if ((battery->state &0x01 ) && (battery->state &0x02 ))seq_printf (seq,"charging state: charging/discharging\n" ); - }else if (battery->state &0x01 ) +else if (battery->state &0x01 )seq_printf (seq,"charging state: discharging\n" );else if (battery->state &0x02 )seq_printf (seq,"charging state: charging\n" ); -else { +else seq_printf (seq,"charging state: charged\n" ); - }if (battery->present_rate ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present rate: unknown\n" );else seq_printf (seq,"present rate: %d %s\n" , - (u32 ) battery->present_rate, units); + battery->present_rate,acpi_battery_units (battery));if (battery->remaining_capacity ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"remaining capacity: unknown\n" );else seq_printf (seq,"remaining capacity: %d %sh\n" , - (u32 ) battery->remaining_capacity, units); - + battery->remaining_capacity,acpi_battery_units (battery));if (battery->present_voltage ==ACPI_BATTERY_VALUE_UNKNOWN )seq_printf (seq,"present voltage: unknown\n" );else seq_printf (seq,"present voltage: %d mV\n" , - (u32 ) battery->present_voltage); - + battery->present_voltage); end: - -if (result) { +if (result)seq_printf (seq,"ERROR: Unable to read battery state\n" ); - }return result; }
@@ -453,7 +401,6 @@ static int acpi_battery_print_state(struct seq_file *seq, int result)static int acpi_battery_print_alarm (struct seq_file *seq,int result) {struct acpi_battery *battery = seq->private; -char *units ="?" ;if (result) goto end;
@@ -462,22 +409,15 @@ static int acpi_battery_print_alarm(struct seq_file *seq, int result)seq_printf (seq,"present: no\n" ); goto end; } - -/* Battery Units */ - - units =acpi_battery_units (battery); -seq_printf (seq,"alarm: " );if (!battery->alarm)seq_printf (seq,"unsupported\n" );else -seq_printf (seq,"%u %sh\n" , battery->alarm, units); - +seq_printf (seq,"%u %sh\n" , battery->alarm, +acpi_battery_units (battery)); end: -if (result)seq_printf (seq,"ERROR: Unable to read battery alarm\n" ); -return result; }
@@ -506,7 +446,7 @@ static ssize_t acpi_battery_write_alarm(struct file *file, } alarm_string[count] ='\0' ; battery->alarm =simple_strtol (alarm_string,NULL ,0 ); - result =acpi_battery_set_alarm (battery, battery->alarm); + result =acpi_battery_set_alarm (battery); end:if (!result)return count;
@@ -514,95 +454,76 @@ static ssize_t acpi_battery_write_alarm(struct file *file, }typedef int (*print_func )(struct seq_file *seq,int result); -typedef int (*get_func )(struct acpi_battery *battery); - -static struct acpi_read_mux { -print_func print; -get_func get; -} acpi_read_funcs[ACPI_BATTERY_NUMFILES ] = { - {.get = acpi_battery_get_info, .print = acpi_battery_print_info}, - {.get = acpi_battery_get_state, .print = acpi_battery_print_state}, - {.get = acpi_battery_get_alarm, .print = acpi_battery_print_alarm}, + +static print_func acpi_print_funcs[ACPI_BATTERY_NUMFILES ] = { + acpi_battery_print_info, + acpi_battery_print_state, + acpi_battery_print_alarm, };static int acpi_battery_read (int fid,struct seq_file *seq) {struct acpi_battery *battery = seq->private;int result =acpi_battery_update (battery); -return acpi_read_funcs[fid].static int acpi_battery_read_info (struct seq_file *seq,void *offset) -{ -return acpi_battery_read (ACPI_BATTERY_INFO , seq); -} - -static int acpi_battery_read_state (struct seq_file *seq,void *offset) -{ -return acpi_battery_read (ACPI_BATTERY_STATE , seq); -} - -static int acpi_battery_read_alarm (struct seq_file *seq,void *offset) -{ -return acpi_battery_read (ACPI_BATTERY_ALARM , seq); +return acpi_print_funcs[fid](seq, result); } -static int acpi_battery_info_open_fs (struct inode *inode,struct file *file) -{ -return single_open (file, acpi_battery_read_info,PDE (inode)->data); +#define DECLARE_FILE_FUNCTIONS (_name) \ +static int acpi_battery_read_##_name(struct seq_file *seq, void *offset) \ +{ \ + return acpi_battery_read(_name##_tag, seq); \ +} \ +static int acpi_battery_##_name##_open_fs(struct inode *inode, struct file *file) \ +{ \ + return single_open(file, acpi_battery_read_##_name, PDE(inode)->data); \ } -static int acpi_battery_state_open_fs (struct inode *inode,struct file *file) -{ -return single_open (file, acpi_battery_read_state,PDE (inode)->data); -} +DECLARE_FILE_FUNCTIONS (info); +DECLARE_FILE_FUNCTIONS (state); +DECLARE_FILE_FUNCTIONS (alarm); + +#undef DECLARE_FILE_FUNCTIONS + +#define FILE_DESCRIPTION_RO (_name) \ + { \ + .name = __stringify(_name), \ + .mode = S_IRUGO, \ + .ops = { \ + .open = acpi_battery_##_name##_open_fs, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + .owner = THIS_MODULE, \ + }, \ + } -static int acpi_battery_alarm_open_fs (struct inode *inode,struct file *file) -{ -return single_open (file, acpi_battery_read_alarm,PDE (inode)->data); -} +#define FILE_DESCRIPTION_RW (_name) \ + { \ + .name = __stringify(_name), \ + .mode = S_IFREG | S_IRUGO | S_IWUSR, \ + .ops = { \ + .open = acpi_battery_##_name##_open_fs, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .write = acpi_battery_write_##_name, \ + .release = single_release, \ + .owner = THIS_MODULE, \ + }, \ + }static struct battery_file {struct file_operations ops;mode_t mode;char *name; } acpi_battery_file[] = { - { - .name ="info" , - .mode =S_IRUGO , - .ops = { - .open = acpi_battery_info_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner =THIS_MODULE , - }, - }, - { - .name ="state" , - .mode =S_IRUGO , - .ops = { - .open = acpi_battery_state_open_fs, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, - .owner =THIS_MODULE , - }, - }, - { - .name ="alarm" , - .mode =S_IFREG |S_IRUGO |S_IWUSR , - .ops = { - .open = acpi_battery_alarm_open_fs, - .read = seq_read, - .write = acpi_battery_write_alarm, - .llseek = seq_lseek, - .release = single_release, - .owner =THIS_MODULE , - }, - }, +FILE_DESCRIPTION_RO (info), +FILE_DESCRIPTION_RO (state), +FILE_DESCRIPTION_RW (alarm), }; +#undef FILE_DESCRIPTION_RO +#undef FILE_DESCRIPTION_RW +static int acpi_battery_add_fs (struct acpi_device *device) {struct proc_dir_entry *entry =NULL ;
@@ -627,23 +548,20 @@ static int acpi_battery_add_fs(struct acpi_device *device) entry->owner =THIS_MODULE ; } } -return 0 ; } -static int acpi_battery_remove_fs (struct acpi_device *device) +static void acpi_battery_remove_fs (struct acpi_device *device) {int i; -if (acpi_device_dir (device)) { -for (i =0 ; i <ACPI_BATTERY_NUMFILES ; ++i) { -remove_proc_entry (acpi_battery_file[i].name, +if (!acpi_device_dir (device)) +return ; +for (i =0 ; i <ACPI_BATTERY_NUMFILES ; ++i) +remove_proc_entry (acpi_battery_file[i].name,acpi_device_dir (device)); - } -remove_proc_entry (acpi_device_bid (device), acpi_battery_dir); -acpi_device_dir (device) =NULL ; - } -return 0 ; +remove_proc_entry (acpi_device_bid (device), acpi_battery_dir); +acpi_device_dir (device) =NULL ; }/* --------------------------------------------------------------------------
@@ -670,14 +588,11 @@ static int acpi_battery_add(struct acpi_device *device)int result =0 ;acpi_status status =0 ;struct acpi_battery *battery =NULL ; -if (!device)return -EINVAL ; - battery =kzalloc (sizeof (struct acpi_battery ),GFP_KERNEL );if (!battery)return -ENOMEM ; - battery->device = device;strcpy (acpi_device_name (device),ACPI_BATTERY_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_BATTERY_CLASS );
@@ -687,7 +602,6 @@ static int acpi_battery_add(struct acpi_device *device) result =acpi_battery_add_fs (device);if (result) goto end; - status =acpi_install_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_battery_notify, battery);
@@ -696,18 +610,14 @@ static int acpi_battery_add(struct acpi_device *device) result = -ENODEV ; goto end; } - printk(KERN_INFO PREFIX "%s Slot [%s] (battery %s)\n",ACPI_BATTERY_DEVICE_NAME ,acpi_device_bid (device), device->status.battery_present ? "present" : "absent"); - end: -if (result) {acpi_battery_remove_fs (device);kfree (battery); } -return result; }
@@ -718,17 +628,13 @@ static int acpi_battery_remove(struct acpi_device *device, int type)if (!device || !acpi_driver_data (device))return -EINVAL ; - battery =acpi_driver_data (device); - status =acpi_remove_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_battery_notify); -acpi_battery_remove_fs (device);mutex_destroy (&battery->lock);kfree (battery); -return 0 ; }
@@ -743,33 +649,35 @@ static int acpi_battery_resume(struct acpi_device *device)return 0 ; } +static struct acpi_driver acpi_battery_driver = { + .name ="battery" , + .class =ACPI_BATTERY_CLASS , + .ids = battery_device_ids, + .ops = { + .add = acpi_battery_add, + .resume = acpi_battery_resume, + .remove = acpi_battery_remove, + }, +}; +static int __init acpi_battery_init (void ) { -int result; -if (acpi_disabled)return -ENODEV ; - acpi_battery_dir =acpi_lock_battery_dir ();if (!acpi_battery_dir)return -ENODEV ; - - result =acpi_bus_register_driver (&acpi_battery_driver); -if (result <0 ) { +if (acpi_bus_register_driver (&acpi_battery_driver) <0 ) {acpi_unlock_battery_dir (acpi_battery_dir);return -ENODEV ; } -return 0 ; } static void __exit acpi_battery_exit(void) {acpi_bus_unregister_driver (&acpi_battery_driver); -acpi_unlock_battery_dir (acpi_battery_dir); - -return ; }module_init (acpi_battery_init);
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 23/37 ACPI: Battery: Add sysfs support
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Refer to Documentation/power_supply_class.txt for interface description.
--- drivers/acpi/Kconfig | 2 +- drivers/acpi/battery.c | 186 ++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 165 insertions(+), 23 deletions(-)
drivers/acpi/Kconfig +1 -1
@@ -97,7 +97,7 @@ config ACPI_AC config ACPI_BATTERY tristate "Battery" - depends on X86 + depends on X86 && POWER_SUPPLY default y help This driver adds support for battery information through
drivers/acpi/battery.c +164 -22
336 lines not on this page · raw message
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 24/37 ACPI: Battery: add sysfs alarm
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/battery.c | 33 ++++++++++++++++++++++++++++++++- 1 files changed, 32 insertions(+), 1 deletions(-)
drivers/acpi/battery.c +32 -1
@@ -687,6 +687,34 @@ static void acpi_battery_remove_fs(struct acpi_device *device) }#endif + +static ssize_t acpi_battery_alarm_show (struct device *dev, +struct device_attribute *attr, +char *buf) +{ +struct acpi_battery *battery =to_acpi_battery (dev_get_drvdata (dev)); +return sprintf (buf,"%d\n" , battery->alarm *1000 ); +} + +static ssize_t acpi_battery_alarm_store (struct device *dev, +struct device_attribute *attr, +const char *buf,size_t count) +{ +unsigned long x; +struct acpi_battery *battery =to_acpi_battery (dev_get_drvdata (dev)); +if (sscanf (buf,"%ld\n" , &x) ==1 ) + battery->alarm = x/1000 ; +if (acpi_battery_present (battery)) +acpi_battery_set_alarm (battery); +return count; +} + +static struct device_attribute alarm_attr = { + .attr = {.name ="alarm" , .mode =0644 , .owner =THIS_MODULE }, + .show = acpi_battery_alarm_show, + .store = acpi_battery_alarm_store, +}; +/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */
@@ -732,6 +760,7 @@ static int acpi_battery_add(struct acpi_device *device) battery->bat.type =POWER_SUPPLY_TYPE_BATTERY ; battery->bat.get_property = acpi_battery_get_property; result =power_supply_register (&battery->device->dev, &battery->bat); + result =device_create_file (battery->bat.dev, &alarm_attr); status =acpi_install_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_battery_notify, battery);
@@ -767,8 +796,10 @@ static int acpi_battery_remove(struct acpi_device *device, int type)#ifdef CONFIG_ACPI_PROCFS acpi_battery_remove_fs (device);#endif -if (battery->bat.dev) +if (battery->bat.dev) { +device_remove_file (battery->bat.dev, &alarm_attr);power_supply_unregister (&battery->bat); + }mutex_destroy (&battery->lock);kfree (battery);return 0 ;
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 25/37 ACPI: Add acpi_bus_generate_event4() function
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
acpi_bus_generate_event() takes two strings out of passed device object. SBS needs to supply these strings directly.
--- drivers/acpi/bus.c | 23 +++++++++++++++-------- drivers/acpi/sbs.c | 46 ++++++++++++++-------------------------------- include/acpi/acpi_bus.h | 1 + 3 files changed, 30 insertions(+), 40 deletions(-)
drivers/acpi/bus.c +15 -8
@@ -284,15 +284,11 @@ DECLARE_WAIT_QUEUE_HEAD(acpi_bus_event_queue);extern int event_is_open; -int acpi_bus_generate_proc_event (struct acpi_device *device,u8 type,int data) +int acpi_bus_generate_proc_event4 (const char *device_class,const char *bus_id,u8 type,int data) { -struct acpi_bus_event *event =NULL ; +struct acpi_bus_event *event;unsigned long flags =0 ; - -if (!device) -return -EINVAL ; -/* drop event on the floor if no one's listening */ if (!event_is_open)return 0 ;
@@ -301,8 +297,8 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)if (!event)return -ENOMEM ; -strcpy (event->device_class, device->pnp.device_class); -strcpy (event->bus_id, device->pnp.bus_id); +strcpy (event->device_class, device_class); +strcpy (event->bus_id, bus_id); event->type = type; event->data = data;
@@ -313,6 +309,17 @@ int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)wake_up_interruptible (&acpi_bus_event_queue);return 0 ; + +} + +EXPORT_SYMBOL_GPL (acpi_bus_generate_proc_event4); + +int acpi_bus_generate_proc_event (struct acpi_device *device,u8 type,int data) +{ +if (!device) +return -EINVAL ; +return acpi_bus_generate_proc_event4 (device->pnp.device_class, + device->pnp.bus_id, type, data); }EXPORT_SYMBOL (acpi_bus_generate_proc_event);
drivers/acpi/sbs.c +14 -32
71 lines not on this page · raw message
include/acpi/acpi_bus.h +1 -0
@@ -333,6 +333,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state);int acpi_bus_set_power (acpi_handle handle,int state);#ifdef CONFIG_ACPI_PROC_EVENT int acpi_bus_generate_proc_event (struct acpi_device *device,u8 type,int data); +int acpi_bus_generate_proc_event4 (const char *class,const char *bid,u8 type,int data);int acpi_bus_receive_event (struct acpi_bus_event *event);#else static inline int acpi_bus_generate_proc_event (struct acpi_device *device,u8 type,int data)
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 26/37 ACPI: EC: Add new query handler to list head.
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/ec.c | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)
drivers/acpi/ec.c +1 -2
@@ -425,7 +425,7 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, handler->func = func; handler->data = data;mutex_lock (&ec->lock); -list_add_tail (&handler->node, &ec->list); +list_add (&handler->node, &ec->list);mutex_unlock (&ec->lock);return 0 ; }
@@ -440,7 +440,6 @@ void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit)if (query_bit == handler->query_bit) {list_del (&handler->node);kfree (handler); -break ; } }mutex_unlock (&ec->lock);
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 27/37 ACPI: SBS: Split host controller (ACPI0001) from SBS driver (ACPI0002)
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Replace poll-based host controller driver with the notify-based one. Split it out of sbs.c.
--- drivers/acpi/Makefile | 1 + drivers/acpi/sbs.c | 374 ++++++++++--------------------------------------- drivers/acpi/sbshc.c | 309 ++++++++++++++++++++++++++++++++++++++++ drivers/acpi/sbshc.h | 27 ++++ 4 files changed, 412 insertions(+), 299 deletions(-) create mode 100644 drivers/acpi/sbshc.c create mode 100644 drivers/acpi/sbshc.h
drivers/acpi/Makefile +1 -0
@@ -60,3 +60,4 @@ obj-$(CONFIG_ACPI_TOSHIBA) += toshiba_acpi.o obj-$(CONFIG_ACPI_HOTPLUG_MEMORY) += acpi_memhotplug.o obj-y += cm_sbs.o obj-$(CONFIG_ACPI_SBS) += sbs.o +obj-$(CONFIG_ACPI_SBS) += sbshc.o
drivers/acpi/sbs.c +75 -299
610 lines not on this page · raw message
drivers/acpi/sbshc.c new file +309 -0
309 lines not on this page · raw message
drivers/acpi/sbshc.h new file +27 -0
@@ -0,0 +1,27 @@ +struct acpi_smb_hc ; +enum acpi_smb_protocol { +SMBUS_WRITE_QUICK =2 , +SMBUS_READ_QUICK =3 , +SMBUS_SEND_BYTE =4 , +SMBUS_RECEIVE_BYTE =5 , +SMBUS_WRITE_BYTE =6 , +SMBUS_READ_BYTE =7 , +SMBUS_WRITE_WORD =8 , +SMBUS_READ_WORD =9 , +SMBUS_WRITE_BLOCK =0xa , +SMBUS_READ_BLOCK =0xb , +SMBUS_PROCESS_CALL =0xc , +SMBUS_BLOCK_PROCESS_CALL =0xd , +}; + +static const u8 SMBUS_PEC =0x80 ; + +typedef void (*smbus_alarm_callback )(void *context); + +extern int acpi_smbus_read (struct acpi_smb_hc *hc,u8 protocol,u8 address, +u8 command,u8 * data); +extern int acpi_smbus_write (struct acpi_smb_hc *hc,u8 protocol,u8 slave_address, +u8 command,u8 * data,u8 length); +extern int acpi_smbus_register_callback (struct acpi_smb_hc *hc, +smbus_alarm_callback callback,void *context); +extern int acpi_smbus_unregister_callback (struct acpi_smb_hc *hc);
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 28/37 ACPI: SBS: Simplify data structures in SBS
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/sbs.c | 282 +++++++++++++++++++++++++--------------------------- 1 files changed, 135 insertions(+), 147 deletions(-)
drivers/acpi/sbs.c +135 -147
@@ -88,10 +88,10 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);/* 0 - every time, > 0 - by update_time */ static unsigned int update_time =120 ; -static unsigned int capacity_mode =CAPACITY_UNIT ; +static unsigned int mode =CAPACITY_UNIT ;module_param (update_time, uint,0644 ); -module_param (capacity_mode, uint,0444 ); +module_param (mode, uint,0444 );static int acpi_sbs_add (struct acpi_device *device);static int acpi_sbs_remove (struct acpi_device *device,int type);
@@ -114,59 +114,43 @@ static struct acpi_driver acpi_sbs_driver = { }, }; -struct acpi_ac { -int ac_present; -}; - -struct acpi_battery_info { -int capacity_mode; -s16 full_charge_capacity; -s16 design_capacity; -s16 design_voltage; -int vscale; -int ipscale; -s16 serial_number; -char manufacturer_name[ACPI_SBS_BLOCK_MAX +3 ]; -char device_name[ACPI_SBS_BLOCK_MAX +3 ]; -char device_chemistry[ACPI_SBS_BLOCK_MAX +3 ]; -}; - -struct acpi_battery_state { -s16 voltage; -s16 amperage; -s16 remaining_capacity; -s16 battery_state; -}; - -struct acpi_battery_alarm { -s16 remaining_capacity; -}; -struct acpi_battery { -int alive; -int id; -int init_state; -int battery_present;struct acpi_sbs *sbs; -struct acpi_battery_info info; -struct acpi_battery_state state; -struct acpi_battery_alarm alarm; -struct proc_dir_entry *battery_entry; +struct proc_dir_entry *proc_entry; +int vscale; +int ipscale; +char manufacturer_name[ACPI_SBS_BLOCK_MAX ]; +char device_name[ACPI_SBS_BLOCK_MAX ]; +char device_chemistry[ACPI_SBS_BLOCK_MAX ]; +u16 full_charge_capacity; +u16 design_capacity; +u16 design_voltage; +u16 serial_number; +u16 voltage_now; +s16 current_now; +u16 capacity_now; +u16 state; +u16 alarm_capacity; +u16 mode; +u8 id; +u8 alive:1 ; +u8 init_state:1 ; +u8 present:1 ; };struct acpi_sbs {struct acpi_device *device;struct acpi_smb_hc *hc;struct mutex mutex; -int sbsm_present; -int sbsm_batteries_supported;struct proc_dir_entry *ac_entry; -struct acpi_ac ac;struct acpi_battery battery[MAX_SBS_BAT ];int zombie;struct timer_list update_timer;int run_cnt;int update_proc_flg; +u8 batteries_supported; +u8 manager_present:1 ; +u8 charger_present:1 ; };static int acpi_sbs_update_run (struct acpi_sbs *sbs,int id,int data_type);
@@ -231,7 +215,7 @@ static int acpi_battery_get_present(struct acpi_battery *battery)if (!result) { is_present = (state &0x000f ) & (1 << battery->id); } - battery->battery_present = is_present; + battery->present = is_present;return result; }
@@ -243,14 +227,14 @@ static int acpi_battery_select(struct acpi_battery *battery)s16 state;int foo; -if (sbs->sbsm_present) { +if (sbs->manager_present) {/* Take special care not to knobble other nibbles of * state (aka selector_state), since * it causes charging to halt on SBSELs */ - result = -acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&state); + result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , +ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&state);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -258,8 +242,8 @@ static int acpi_battery_select(struct acpi_battery *battery) } foo = (state &0x0fff ) | (1 << (battery->id +12 )); - result = -acpi_smbus_write (battery->sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&foo,2 ); + result =acpi_smbus_write (battery->sbs->hc,SMBUS_WRITE_WORD , +ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&foo,2 );if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_write() failed" ));
@@ -283,8 +267,7 @@ static int acpi_sbsm_get_info(struct acpi_sbs *sbs) "acpi_smbus_read() failed")); goto end; } - sbs->sbsm_present =1 ; - sbs->sbsm_batteries_supported = battery_system_info &0x000f ; + sbs->manager_present =1 ; end:
@@ -304,10 +287,10 @@ static int acpi_battery_get_info(struct acpi_battery *battery) "acpi_smbus_read() failed")); goto end; } - battery->info.capacity_mode = (battery_mode &0x8000 ) >>15 ; + battery->mode = (battery_mode &0x8000 ) >>15 ; result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x10 , - (u8 *)&battery->info.full_charge_capacity); + (u8 *)&battery->full_charge_capacity);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -315,7 +298,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x18 , - (u8 *)&battery->info.design_capacity); + (u8 *)&battery->design_capacity);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -324,7 +307,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x19 , - (u8 *)&battery->info.design_voltage); + (u8 *)&battery->design_voltage);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -341,34 +324,34 @@ static int acpi_battery_get_info(struct acpi_battery *battery)switch ((specification_info &0x0f00 ) >>8 ) {case 1 : - battery->info.vscale =10 ; + battery->vscale =10 ;break ;case 2 : - battery->info.vscale =100 ; + battery->vscale =100 ;break ;case 3 : - battery->info.vscale =1000 ; + battery->vscale =1000 ;break ;default : - battery->info.vscale =1 ; + battery->vscale =1 ; }switch ((specification_info &0xf000 ) >>12 ) {case 1 : - battery->info.ipscale =10 ; + battery->ipscale =10 ;break ;case 2 : - battery->info.ipscale =100 ; + battery->ipscale =100 ;break ;case 3 : - battery->info.ipscale =1000 ; + battery->ipscale =1000 ;break ;default : - battery->info.ipscale =1 ; + battery->ipscale =1 ; } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x1c , - (u8 *)&battery->info.serial_number); + (u8 *)&battery->serial_number);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -376,7 +359,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x20 , - (u8 *)battery->info.manufacturer_name); + (u8 *)battery->manufacturer_name);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_sbs_read_str() failed" ));
@@ -384,7 +367,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x21 , - (u8 *)battery->info.device_name); + (u8 *)battery->device_name);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_sbs_read_str() failed" ));
@@ -392,7 +375,7 @@ static int acpi_battery_get_info(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x22 , - (u8 *)battery->info.device_chemistry); + (u8 *)battery->device_chemistry);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_sbs_read_str() failed" ));
@@ -408,7 +391,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery)int result =0 ; result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x09 , - (u8 *)&battery->state.voltage); + (u8 *)&battery->voltage_now);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -416,7 +399,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x0a , - (u8 *)&battery->state.amperage); + (u8 *)&battery->current_now);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -424,7 +407,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x0f , - (u8 *)&battery->state.remaining_capacity); + (u8 *)&battery->capacity_now);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -432,7 +415,7 @@ static int acpi_battery_get_state(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x16 , - (u8 *)&battery->state.battery_state); + (u8 *)&battery->state);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -448,7 +431,7 @@ static int acpi_battery_get_alarm(struct acpi_battery *battery)int result =0 ; result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , - (u8 *)&battery->alarm.remaining_capacity); + (u8 *)&battery->alarm_capacity);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -497,8 +480,9 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery, } } - foo = alarm / (battery->info.capacity_mode ?10 :1 ); - result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , (u8 *)&foo,2 ); + foo = alarm / (battery->mode ?10 :1 ); + result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , + (u8 *)&foo,2 );if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_write() failed" ));
@@ -515,25 +499,25 @@ static int acpi_battery_set_mode(struct acpi_battery *battery)int result =0 ;s16 battery_mode; -if (capacity_mode ==DEF_CAPACITY_UNIT ) { +if (mode ==DEF_CAPACITY_UNIT ) { goto end; } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode); +ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" )); goto end; } -if (capacity_mode ==MAH_CAPACITY_UNIT ) { +if (mode ==MAH_CAPACITY_UNIT ) { battery_mode &=0x7fff ; }else { battery_mode |=0x8000 ; } result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode,2 ); +ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode,2 );if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_write() failed" ));
@@ -541,7 +525,7 @@ static int acpi_battery_set_mode(struct acpi_battery *battery) } result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode); +ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode);if (result) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_smbus_read() failed" ));
@@ -601,7 +585,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)s16 charger_status; result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBC_SMBUS_ADDR ,0x13 , - (u8 *)&charger_status); + (u8 *)&charger_status);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -609,7 +593,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs) goto end; } - sbs->ac.ac_present = (charger_status &0x8000 ) >>15 ; + sbs->charger_present = (charger_status &0x8000 ) >>15 ; end:
@@ -726,30 +710,30 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset) } } -if (battery->battery_present) { +if (battery->present) {seq_printf (seq,"present: yes\n" ); }else {seq_printf (seq,"present: no\n" ); goto end; } -if (battery->info.capacity_mode) { - cscale = battery->info.vscale * battery->info.ipscale; +if (battery->mode) { + cscale = battery->vscale * battery->ipscale; }else { - cscale = battery->info.ipscale; + cscale = battery->ipscale; }seq_printf (seq,"design capacity: %i%s\n" , - battery->info.design_capacity * cscale, - battery->info.capacity_mode ?"0 mWh" :" mAh" ); + battery->design_capacity * cscale, + battery->mode ?"0 mWh" :" mAh" );seq_printf (seq,"last full capacity: %i%s\n" , - battery->info.full_charge_capacity * cscale, - battery->info.capacity_mode ?"0 mWh" :" mAh" ); + battery->full_charge_capacity * cscale, + battery->mode ?"0 mWh" :" mAh" );seq_printf (seq,"battery technology: rechargeable\n" );seq_printf (seq,"design voltage: %i mV\n" , - battery->info.design_voltage * battery->info.vscale); + battery->design_voltage * battery->vscale);seq_printf (seq,"design capacity warning: unknown\n" );seq_printf (seq,"design capacity low: unknown\n" );
@@ -757,16 +741,16 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)seq_printf (seq,"capacity granularity 2: unknown\n" );seq_printf (seq,"model number: %s\n" , - battery->info.device_name); + battery->device_name);seq_printf (seq,"serial number: %i\n" , - battery->info.serial_number); + battery->serial_number);seq_printf (seq,"battery type: %s\n" , - battery->info.device_chemistry); + battery->device_chemistry);seq_printf (seq,"OEM info: %s\n" , - battery->info.manufacturer_name); + battery->manufacturer_name); end:
@@ -804,49 +788,49 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset) } } -if (battery->battery_present) { +if (battery->present) {seq_printf (seq,"present: yes\n" ); }else {seq_printf (seq,"present: no\n" ); goto end; } -if (battery->info.capacity_mode) { - cscale = battery->info.vscale * battery->info.ipscale; +if (battery->mode) { + cscale = battery->vscale * battery->ipscale; }else { - cscale = battery->info.ipscale; + cscale = battery->ipscale; } -if (battery->state.battery_state &0x0010 ) { +if (battery->state &0x0010 ) {seq_printf (seq,"capacity state: critical\n" ); }else {seq_printf (seq,"capacity state: ok\n" ); } - foo = (s16 ) battery->state.amperage * battery->info.ipscale; -if (battery->info.capacity_mode) { - foo = foo * battery->info.design_voltage /1000 ; + foo = (s16 ) battery->current_now * battery->ipscale; +if (battery->mode) { + foo = foo * battery->design_voltage /1000 ; } -if (battery->state.amperage <0 ) { +if (battery->current_now <0 ) {seq_printf (seq,"charging state: discharging\n" );seq_printf (seq,"present rate: %d %s\n" , - -foo, battery->info.capacity_mode ?"mW" :"mA" ); - }else if (battery->state.amperage >0 ) { + -foo, battery->mode ?"mW" :"mA" ); + }else if (battery->current_now >0 ) {seq_printf (seq,"charging state: charging\n" );seq_printf (seq,"present rate: %d %s\n" , - foo, battery->info.capacity_mode ?"mW" :"mA" ); + foo, battery->mode ?"mW" :"mA" ); }else {seq_printf (seq,"charging state: charged\n" );seq_printf (seq,"present rate: 0 %s\n" , - battery->info.capacity_mode ?"mW" :"mA" ); + battery->mode ?"mW" :"mA" ); }seq_printf (seq,"remaining capacity: %i%s\n" , - battery->state.remaining_capacity * cscale, - battery->info.capacity_mode ?"0 mWh" :" mAh" ); + battery->capacity_now * cscale, + battery->mode ?"0 mWh" :" mAh" );seq_printf (seq,"present voltage: %i mV\n" , - battery->state.voltage * battery->info.vscale); + battery->voltage_now * battery->vscale); end:
@@ -883,22 +867,22 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset) } } -if (!battery->battery_present) { +if (!battery->present) {seq_printf (seq,"present: no\n" ); goto end; } -if (battery->info.capacity_mode) { - cscale = battery->info.vscale * battery->info.ipscale; +if (battery->mode) { + cscale = battery->vscale * battery->ipscale; }else { - cscale = battery->info.ipscale; + cscale = battery->ipscale; }seq_printf (seq,"alarm: " ); -if (battery->alarm.remaining_capacity) { +if (battery->alarm_capacity) {seq_printf (seq,"%i%s\n" , - battery->alarm.remaining_capacity * cscale, - battery->info.capacity_mode ?"0 mWh" :" mAh" ); + battery->alarm_capacity * cscale, + battery->mode ?"0 mWh" :" mAh" ); }else {seq_printf (seq,"disabled\n" ); }
@@ -928,7 +912,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,if (result) goto end; -if (!battery->battery_present) { +if (!battery->present) { result = -ENODEV ; goto end; }
@@ -945,7 +929,7 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer, alarm_string[count] =0 ; - old_alarm = battery->alarm.remaining_capacity; + old_alarm = battery->alarm_capacity; new_alarm =simple_strtoul (alarm_string,NULL ,0 ); result =acpi_battery_set_alarm (battery, new_alarm);
@@ -1025,7 +1009,7 @@ static int acpi_ac_read_state(struct seq_file *seq, void *offset) }seq_printf (seq,"state: %s\n" , - sbs->ac.ac_present ?"on-line" :"off-line" ); + sbs->charger_present ?"on-line" :"off-line" );sbs_mutex_unlock (sbs);
@@ -1080,7 +1064,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) goto end; } - is_present = battery->battery_present; + is_present = battery->present;if (is_present) { result =acpi_battery_init (battery);
@@ -1094,7 +1078,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); - result = acpi_sbs_generic_add_fs(&battery->battery_entry, + result = acpi_sbs_generic_add_fs(&battery->proc_entry, acpi_battery_dir, dir_name, &acpi_battery_info_fops,
@@ -1109,7 +1093,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), dir_name, - sbs->battery->battery_present ? "present" : "absent"); + sbs->battery->present ? "present" : "absent"); end:return result;
@@ -1118,8 +1102,8 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)static void acpi_battery_remove (struct acpi_sbs *sbs,int id) { -if (sbs->battery[id].battery_entry) { -acpi_sbs_generic_remove_fs (&(sbs->battery[id].battery_entry), +if (sbs->battery[id].proc_entry) { +acpi_sbs_generic_remove_fs (&(sbs->battery[id].proc_entry), acpi_battery_dir); } }
@@ -1147,7 +1131,7 @@ static int acpi_ac_add(struct acpi_sbs *sbs) printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), - ACPI_AC_DIR_NAME, sbs->ac.ac_present ? "on-line" : "off-line"); + ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); end:
@@ -1172,9 +1156,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)struct acpi_battery *battery;int result =0 , cnt;int old_ac_present =-1 ; -int old_battery_present =-1 ; +int old_present =-1 ;int new_ac_present =-1 ; -int new_battery_present =-1 ; +int new_present =-1 ;int id_min =0 , id_max =MAX_SBS_BAT -1 ;char dir_name[32 ];int do_battery_init =0 , do_ac_init =0 ;
@@ -1199,7 +1183,11 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) sbs->run_cnt++; - old_ac_present = sbs->ac.ac_present; +if (!update_battery) { + goto end; + } + + old_ac_present = sbs->charger_present; result =acpi_ac_get_present (sbs);if (result) {
@@ -1207,7 +1195,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) "acpi_ac_get_present() failed")); } - new_ac_present = sbs->ac.ac_present; + new_ac_present = sbs->charger_present; do_ac_init = (old_ac_present != new_ac_present);if (sbs->run_cnt ==1 && data_type ==DATA_TYPE_COMMON ) {
@@ -1244,9 +1232,9 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)continue ; } - old_remaining_capacity = battery->state.remaining_capacity; + old_remaining_capacity = battery->capacity_now; - old_battery_present = battery->battery_present; + old_present = battery->present; result =acpi_battery_select (battery);if (result) {
@@ -1260,11 +1248,11 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) "acpi_battery_get_present() failed")); } - new_battery_present = battery->battery_present; + new_present = battery->present; - do_battery_init = ((old_battery_present != new_battery_present) - && new_battery_present); -if (!new_battery_present) + do_battery_init = ((old_present != new_present) + && new_present); +if (!new_present) goto event;if (do_ac_init || do_battery_init) { result =acpi_battery_init (battery);
@@ -1280,7 +1268,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)if ((data_type ==DATA_TYPE_COMMON || data_type ==DATA_TYPE_INFO ) - && new_battery_present) { + && new_present) { result =acpi_battery_get_info (battery);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1296,7 +1284,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)if ((data_type ==DATA_TYPE_COMMON || data_type ==DATA_TYPE_STATE ) - && new_battery_present) { + && new_present) { result =acpi_battery_get_state (battery);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1312,7 +1300,7 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type)if ((data_type ==DATA_TYPE_COMMON || data_type ==DATA_TYPE_ALARM ) - && new_battery_present) { + && new_present) { result =acpi_battery_get_alarm (battery);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1329,17 +1317,17 @@ static int acpi_sbs_update_run(struct acpi_sbs *sbs, int id, int data_type) event: -if (old_battery_present != new_battery_present || do_ac_init || +if (old_present != new_present || do_ac_init || old_remaining_capacity != - battery->state.remaining_capacity) { + battery->capacity_now) {sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); result =acpi_bus_generate_proc_event4 (ACPI_BATTERY_CLASS , dir_name,ACPI_SBS_BATTERY_NOTIFY_STATUS , - new_battery_present); + new_present);acpi_bus_generate_netlink_event (ACPI_BATTERY_CLASS , dir_name,ACPI_SBS_BATTERY_NOTIFY_STATUS , - new_battery_present); + new_present);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR, "acpi_bus_generate_proc_event4() "
@@ -1426,7 +1414,7 @@ static int acpi_sbs_add(struct acpi_device *device)acpi_sbsm_get_info (sbs); -if (!sbs->sbsm_present) { +if (!sbs->manager_present) { result =acpi_battery_add (sbs,0 );if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1435,7 +1423,7 @@ static int acpi_sbs_add(struct acpi_device *device) } }else {for (id =0 ; id <MAX_SBS_BAT ; id++) { -if ((sbs->sbsm_batteries_supported & (1 << id))) { +if ((sbs->batteries_supported & (1 << id))) { result =acpi_battery_add (sbs, id);if (result) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
@@ -1535,11 +1523,11 @@ static int __init acpi_sbs_init(void)if (acpi_disabled)return -ENODEV ; -if (capacity_mode !=DEF_CAPACITY_UNIT - && capacity_mode !=MAH_CAPACITY_UNIT - && capacity_mode !=MWH_CAPACITY_UNIT ) { +if (mode !=DEF_CAPACITY_UNIT + && mode !=MAH_CAPACITY_UNIT + && mode !=MWH_CAPACITY_UNIT ) {ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"invalid capacity_mode = %d" , capacity_mode)); +"invalid mode = %d" , mode));return -EINVAL ; }
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 29/37 ACPI: SBS: Make SBS reads table-driven.
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Re-factor SBS functions to use tables and cycles for repeated operations.
--- drivers/acpi/sbs.c | 1292 +++++++++++----------------------------------------- 1 files changed, 275 insertions(+), 1017 deletions(-)
drivers/acpi/sbs.c +275 -1017
@@ -1,6 +1,8 @@/* -* acpi_sbs.c - ACPI Smart Battery System Driver ($Revision: 1.16 $) +* sbs.c - ACPI Smart Battery System Driver ($Revision: 2.0 $) * +* Copyright (c) 2007 Alexey Starikovskiy <[email protected]> +* Copyright (c) 2005-2007 Vladimir Lebedev <[email protected]> * Copyright (c) 2005 Rich Townsend <[email protected]> * * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -46,53 +48,34 @@#define ACPI_SBS_FILE_ALARM "alarm"#define ACPI_BATTERY_DIR_NAME "BAT%i"#define ACPI_AC_DIR_NAME "AC0" -#define ACPI_SBC_SMBUS_ADDR 0x9 -#define ACPI_SBSM_SMBUS_ADDR 0xa -#define ACPI_SB_SMBUS_ADDR 0xb -#define ACPI_SBS_AC_NOTIFY_STATUS 0x80 -#define ACPI_SBS_BATTERY_NOTIFY_STATUS 0x80 -#define ACPI_SBS_BATTERY_NOTIFY_INFO 0x81 -#define _COMPONENT ACPI_SBS_COMPONENT +enum acpi_sbs_device_addr { +ACPI_SBS_CHARGER =0x9 , +ACPI_SBS_MANAGER =0xa , +ACPI_SBS_BATTERY =0xb , +}; + +#define ACPI_SBS_NOTIFY_STATUS 0x80 +#define ACPI_SBS_NOTIFY_INFO 0x81ACPI_MODULE_NAME ("sbs" ); -MODULE_AUTHOR ("Rich Townsend" ); +MODULE_AUTHOR ("Alexey Starikovskiy <[email protected]>" );MODULE_DESCRIPTION ("Smart Battery System ACPI interface driver" );MODULE_LICENSE ("GPL" ); -#define DEF_CAPACITY_UNIT 3 -#define MAH_CAPACITY_UNIT 1 -#define MWH_CAPACITY_UNIT 2 -#define CAPACITY_UNIT DEF_CAPACITY_UNIT - -#define REQUEST_UPDATE_MODE 1 -#define QUEUE_UPDATE_MODE 2 - -#define DATA_TYPE_COMMON 0 -#define DATA_TYPE_INFO 1 -#define DATA_TYPE_STATE 2 -#define DATA_TYPE_ALARM 3 -#define DATA_TYPE_AC_STATE 4 +static unsigned int cache_time =1000 ; +module_param (cache_time, uint,0644 ); +MODULE_PARM_DESC (cache_time,"cache time in milliseconds" );extern struct proc_dir_entry *acpi_lock_ac_dir (void );extern struct proc_dir_entry *acpi_lock_battery_dir (void );extern void acpi_unlock_ac_dir (struct proc_dir_entry *acpi_ac_dir);extern void acpi_unlock_battery_dir (struct proc_dir_entry *acpi_battery_dir); -#define MAX_SBS_BAT 4 +#define MAX_SBS_BAT 4#define ACPI_SBS_BLOCK_MAX 32 -#define UPDATE_DELAY 10 - -/* 0 - every time, > 0 - by update_time */ -static unsigned int update_time =120 ; - -static unsigned int mode =CAPACITY_UNIT ; - -module_param (update_time, uint,0644 ); -module_param (mode, uint,0444 ); -static int acpi_sbs_add (struct acpi_device *device);static int acpi_sbs_remove (struct acpi_device *device,int type);static int acpi_sbs_resume (struct acpi_device *device);
@@ -117,486 +100,187 @@ static struct acpi_driver acpi_sbs_driver = {struct acpi_battery {struct acpi_sbs *sbs;struct proc_dir_entry *proc_entry; -int vscale; -int ipscale; +unsigned long update_time; +char name[8 ];char manufacturer_name[ACPI_SBS_BLOCK_MAX ];char device_name[ACPI_SBS_BLOCK_MAX ];char device_chemistry[ACPI_SBS_BLOCK_MAX ]; +u32 alarm_capacity;u16 full_charge_capacity;u16 design_capacity;u16 design_voltage;u16 serial_number; +u16 cycle_count; +u16 temp_now;u16 voltage_now;s16 current_now; +s16 current_avg;u16 capacity_now; +u16 state_of_charge;u16 state; -u16 alarm_capacity;u16 mode; +u16 spec;u8 id; -u8 alive:1 ; -u8 init_state:1 ;u8 present:1 ; };struct acpi_sbs {struct acpi_device *device;struct acpi_smb_hc *hc; -struct mutex mutex; -struct proc_dir_entry *ac_entry; +struct mutex lock; +struct proc_dir_entry *charger_entry;struct acpi_battery battery[MAX_SBS_BAT ]; -int zombie; -struct timer_list update_timer; -int run_cnt; -int update_proc_flg; -u8 batteries_supported; +u8 batteries_supported:4 ;u8 manager_present:1 ;u8 charger_present:1 ; }; -static int acpi_sbs_update_run (struct acpi_sbs *sbs,int id,int data_type); -static void acpi_sbs_update_time (void *data); - -static int sbs_zombie (struct acpi_sbs *sbs) +static inline int battery_scale (int log) { -return (sbs->zombie); +int scale =1 ; +while (log--) + scale *=10 ; +return scale; } -static int sbs_mutex_lock (struct acpi_sbs *sbs) +static inline int acpi_battery_vscale (struct acpi_battery *battery) { -if (sbs_zombie (sbs)) { -return -ENODEV ; - } -mutex_lock (&sbs->mutex); -return 0 ; +return battery_scale ((battery->spec &0x0f00 ) >>8 ); } -static void sbs_mutex_unlock (struct acpi_sbs *sbs) +static inline int acpi_battery_ipscale (struct acpi_battery *battery) { -mutex_unlock (&sbs->mutex); +return battery_scale ((battery->spec &0xf000 ) >>12 ); } -/* -------------------------------------------------------------------------- -Smart Battery System Management --------------------------------------------------------------------------- */ - -static int acpi_check_update_proc (struct acpi_sbs *sbs) +static inline int acpi_battery_mode (struct acpi_battery *battery) { -acpi_status status =AE_OK ; - -if (update_time ==0 ) { - sbs->update_proc_flg =0 ; -return 0 ; - } -if (sbs->update_proc_flg ==0 ) { - status =acpi_os_execute (OSL_GPE_HANDLER , - acpi_sbs_update_time, sbs); -if (status !=AE_OK ) { -ACPI_EXCEPTION ((AE_INFO , status, -"acpi_os_execute() failed" )); -return 1 ; - } - sbs->update_proc_flg =1 ; - } -return 0 ; +return (battery->mode &0x8000 ); } -static int acpi_battery_get_present (struct acpi_battery *battery) +static inline int acpi_battery_scale (struct acpi_battery *battery) { -s16 state; -int result =0 ; -int is_present =0 ; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&state); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - } -if (!result) { - is_present = (state &0x000f ) & (1 << battery->id); - } - battery->present = is_present; - -return result; +return (acpi_battery_mode (battery) ?10 :1 ) * +acpi_battery_ipscale (battery); } -static int acpi_battery_select (struct acpi_battery *battery) -{ -struct acpi_sbs *sbs = battery->sbs; -int result =0 ; -s16 state; -int foo; - -if (sbs->manager_present) { - -/* Take special care not to knobble other nibbles of -* state (aka selector_state), since -* it causes charging to halt on SBSELs */ +/* -------------------------------------------------------------------------- +Smart Battery System Management +-------------------------------------------------------------------------- */ - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&state); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } +struct acpi_battery_reader { +u8 command;/* command for battery */ +u8 mode;/* word or block? */ +size_t offset;/* offset inside struct acpi_sbs_battery */ +}; - foo = (state &0x0fff ) | (1 << (battery->id +12 )); - result =acpi_smbus_write (battery->sbs->hc,SMBUS_WRITE_WORD , -ACPI_SBSM_SMBUS_ADDR ,0x01 , (u8 *)&foo,2 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_write() failed" )); - goto end; - } - } +static struct acpi_battery_reader info_readers[] = { + {0x01 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , alarm_capacity)}, + {0x03 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , mode)}, + {0x10 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , full_charge_capacity)}, + {0x17 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , cycle_count)}, + {0x18 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , design_capacity)}, + {0x19 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , design_voltage)}, + {0x1a ,SMBUS_READ_WORD , offsetof(struct acpi_battery , spec)}, + {0x1c ,SMBUS_READ_WORD , offsetof(struct acpi_battery , serial_number)}, + {0x20 ,SMBUS_READ_BLOCK , offsetof(struct acpi_battery , manufacturer_name)}, + {0x21 ,SMBUS_READ_BLOCK , offsetof(struct acpi_battery , device_name)}, + {0x22 ,SMBUS_READ_BLOCK , offsetof(struct acpi_battery , device_chemistry)}, +}; - end: -return result; -} +static struct acpi_battery_reader state_readers[] = { + {0x08 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , temp_now)}, + {0x09 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , voltage_now)}, + {0x0a ,SMBUS_READ_WORD , offsetof(struct acpi_battery , current_now)}, + {0x0b ,SMBUS_READ_WORD , offsetof(struct acpi_battery , current_avg)}, + {0x0f ,SMBUS_READ_WORD , offsetof(struct acpi_battery , capacity_now)}, + {0x0e ,SMBUS_READ_WORD , offsetof(struct acpi_battery , state_of_charge)}, + {0x16 ,SMBUS_READ_WORD , offsetof(struct acpi_battery , state)}, +}; -static int acpi_sbsm_get_info (struct acpi_sbs *sbs) +static int acpi_manager_get_info (struct acpi_sbs *sbs) {int result =0 ; -s16 battery_system_info; - - result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBSM_SMBUS_ADDR ,0x04 , - (u8 *)&battery_system_info); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - sbs->manager_present =1 ; - - end: +u16 battery_system_info; + result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_MANAGER , +0x04 , (u8 *) & battery_system_info); +if (!result) + sbs->batteries_supported = battery_system_info &0x000f ;return result; }static int acpi_battery_get_info (struct acpi_battery *battery) { -int result =0 ; -s16 battery_mode; -s16 specification_info; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x03 , - (u8 *)&battery_mode); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - battery->mode = (battery_mode &0x8000 ) >>15 ; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x10 , - (u8 *)&battery->full_charge_capacity); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x18 , - (u8 *)&battery->design_capacity); +int i, result =0 ; -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x19 , - (u8 *)&battery->design_voltage); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; +for (i =0 ; i <ARRAY_SIZE (info_readers); ++i) { + result =acpi_smbus_read (battery->sbs->hc, info_readers[i].mode, +ACPI_SBS_BATTERY , info_readers[i].command, + (u8 *) battery + info_readers[i].offset); +if (result) +break ; } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x1a , - (u8 *)&specification_info); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - -switch ((specification_info &0x0f00 ) >>8 ) { -case 1 : - battery->vscale =10 ; -break ; -case 2 : - battery->vscale =100 ; -break ; -case 3 : - battery->vscale =1000 ; -break ; -default : - battery->vscale =1 ; - } - -switch ((specification_info &0xf000 ) >>12 ) { -case 1 : - battery->ipscale =10 ; -break ; -case 2 : - battery->ipscale =100 ; -break ; -case 3 : - battery->ipscale =1000 ; -break ; -default : - battery->ipscale =1 ; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x1c , - (u8 *)&battery->serial_number); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x20 , - (u8 *)battery->manufacturer_name); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_read_str() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x21 , - (u8 *)battery->device_name); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_read_str() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_BLOCK ,ACPI_SB_SMBUS_ADDR ,0x22 , - (u8 *)battery->device_chemistry); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_read_str() failed" )); - goto end; - } - - end:return result; }static int acpi_battery_get_state (struct acpi_battery *battery) { -int result =0 ; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x09 , - (u8 *)&battery->voltage_now); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x0a , - (u8 *)&battery->current_now); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x0f , - (u8 *)&battery->capacity_now); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x16 , - (u8 *)&battery->state); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - end: -return result; -} - -static int acpi_battery_get_alarm (struct acpi_battery *battery) -{ -int result =0 ; - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , - (u8 *)&battery->alarm_capacity); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - end: - -return result; -} - -static int acpi_battery_set_alarm (struct acpi_battery *battery, -unsigned long alarm) -{ -int result =0 ; -s16 battery_mode; -int foo; +int i, result =0 ; - result =acpi_battery_select (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_select() failed" )); - goto end; - } - -/* If necessary, enable the alarm */ - -if (alarm >0 ) { - result = -acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x03 , - (u8 *)&battery_mode); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - battery_mode &=0xbfff ; - result = -acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , - (u8 *)&battery_mode,2 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_write() failed" )); +if (time_before (jiffies, battery->update_time + +msecs_to_jiffies (cache_time))) +return 0 ; +for (i =0 ; i <ARRAY_SIZE (state_readers); ++i) { + result =acpi_smbus_read (battery->sbs->hc, + state_readers[i].mode, +ACPI_SBS_BATTERY , + state_readers[i].command, + (u8 *)battery + + state_readers[i].offset); +if (result) goto end; - } } - - foo = alarm / (battery->mode ?10 :1 ); - result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD ,ACPI_SB_SMBUS_ADDR ,0x01 , - (u8 *)&foo,2 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_write() failed" )); - goto end; - } - end: - + battery->update_time = jiffies;return result; } -static int acpi_battery_set_mode (struct acpi_battery *battery) +static int acpi_battery_get_alarm (struct acpi_battery *battery) { -int result =0 ; -s16 battery_mode; - -if (mode ==DEF_CAPACITY_UNIT ) { - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - -if (mode ==MAH_CAPACITY_UNIT ) { - battery_mode &=0x7fff ; - }else { - battery_mode |=0x8000 ; - } - result =acpi_smbus_write (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode,2 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_write() failed" )); - goto end; - } - - result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , -ACPI_SB_SMBUS_ADDR ,0x03 , (u8 *)&battery_mode); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - end: -return result; +return acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , +ACPI_SBS_BATTERY ,0x01 , + (u8 *) & battery->alarm_capacity); } -static int acpi_battery_init (struct acpi_battery *battery) +static int acpi_battery_set_alarm (struct acpi_battery *battery) { -int result =0 ; - - result =acpi_battery_select (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_select() failed" )); - goto end; - } - - result =acpi_battery_set_mode (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_set_mode() failed" )); - goto end; - } - - result =acpi_battery_get_info (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_info() failed" )); - goto end; - } - - result =acpi_battery_get_state (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_state() failed" )); - goto end; - } +struct acpi_sbs *sbs = battery->sbs; +u16 value; +return 0 ; - result =acpi_battery_get_alarm (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_alarm() failed" )); - goto end; +if (sbs->manager_present) { +acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_MANAGER , +0x01 , (u8 *)&value); + value &=0x0fff ; + value |=1 << (battery->id +12 ); +acpi_smbus_write (sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBS_MANAGER , +0x01 , (u8 *)&value,2 ); } - - end: -return result; + value = battery->alarm_capacity / (acpi_battery_mode (battery) ?10 :1 ); +return acpi_smbus_write (sbs->hc,SMBUS_WRITE_WORD ,ACPI_SBS_BATTERY , +0x01 , (u8 *)&value,2 ); }static int acpi_ac_get_present (struct acpi_sbs *sbs) { -int result =0 ; -s16 charger_status; - - result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBC_SMBUS_ADDR ,0x13 , - (u8 *)&charger_status); - -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_smbus_read() failed" )); - goto end; - } - - sbs->charger_present = (charger_status &0x8000 ) >>15 ; - - end: +int result; +u16 status; + result =acpi_smbus_read (sbs->hc,SMBUS_READ_WORD ,ACPI_SBS_CHARGER , +0x13 , (u8 *) & status); +if (!result) + sbs->charger_present = (status >>15 ) &0x1 ;return result; }
@@ -607,7 +291,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)/* Generic Routines */ static int -acpi_sbs_generic_add_fs(struct proc_dir_entry **dir, +acpi_sbs_add_fs(struct proc_dir_entry **dir, struct proc_dir_entry *parent_dir, char *dir_name, struct file_operations *info_fops,
@@ -669,7 +353,7 @@ acpi_sbs_generic_add_fs(struct proc_dir_entry **dir, }static void -acpi_sbs_generic_remove_fs (struct proc_dir_entry **dir, +acpi_sbs_remove_fs (struct proc_dir_entry **dir,struct proc_dir_entry *parent_dir) {
@@ -687,75 +371,47 @@ acpi_sbs_generic_remove_fs(struct proc_dir_entry **dir,static struct proc_dir_entry *acpi_battery_dir =NULL ; +static inline char *acpi_battery_units (struct acpi_battery *battery) +{ +return acpi_battery_mode (battery) ?" mWh" :" mAh" ; +} + +static int acpi_battery_read_info (struct seq_file *seq,void *offset) {struct acpi_battery *battery = seq->private;struct acpi_sbs *sbs = battery->sbs; -int cscale;int result =0 ; -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } +mutex_lock (&sbs->lock); - result =acpi_check_update_proc (sbs); -if (result) +seq_printf (seq,"present: %s\n" , + (battery->present) ?"yes" :"no" ); +if (!battery->present) goto end; -if (update_time ==0 ) { - result =acpi_sbs_update_run (sbs, battery->id,DATA_TYPE_INFO ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - } - -if (battery->present) { -seq_printf (seq,"present: yes\n" ); - }else { -seq_printf (seq,"present: no\n" ); - goto end; - } - -if (battery->mode) { - cscale = battery->vscale * battery->ipscale; - }else { - cscale = battery->ipscale; - }seq_printf (seq,"design capacity: %i%s\n" , - battery->design_capacity * cscale, - battery->mode ?"0 mWh" :" mAh" ); - + battery->design_capacity *acpi_battery_scale (battery), +acpi_battery_units (battery));seq_printf (seq,"last full capacity: %i%s\n" , - battery->full_charge_capacity * cscale, - battery->mode ?"0 mWh" :" mAh" ); - + battery->full_charge_capacity *acpi_battery_scale (battery), +acpi_battery_units (battery));seq_printf (seq,"battery technology: rechargeable\n" ); -seq_printf (seq,"design voltage: %i mV\n" , - battery->design_voltage * battery->vscale); - + battery->design_voltage *acpi_battery_vscale (battery));seq_printf (seq,"design capacity warning: unknown\n" );seq_printf (seq,"design capacity low: unknown\n" );seq_printf (seq,"capacity granularity 1: unknown\n" );seq_printf (seq,"capacity granularity 2: unknown\n" ); - -seq_printf (seq,"model number: %s\n" , - battery->device_name); - +seq_printf (seq,"model number: %s\n" , battery->device_name);seq_printf (seq,"serial number: %i\n" , battery->serial_number); -seq_printf (seq,"battery type: %s\n" , battery->device_chemistry); -seq_printf (seq,"OEM info: %s\n" , battery->manufacturer_name); - end: - -sbs_mutex_unlock (sbs); - +mutex_unlock (&sbs->lock);return result; }
@@ -769,73 +425,29 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)struct acpi_battery *battery = seq->private;struct acpi_sbs *sbs = battery->sbs;int result =0 ; -int cscale; -int foo; - -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } - - result =acpi_check_update_proc (sbs); -if (result) - goto end; - -if (update_time ==0 ) { - result =acpi_sbs_update_run (sbs, battery->id,DATA_TYPE_STATE ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - } -if (battery->present) { -seq_printf (seq,"present: yes\n" ); - }else { -seq_printf (seq,"present: no\n" ); +mutex_lock (&sbs->lock); +seq_printf (seq,"present: %s\n" , + (battery->present) ?"yes" :"no" ); +if (!battery->present) goto end; - } - -if (battery->mode) { - cscale = battery->vscale * battery->ipscale; - }else { - cscale = battery->ipscale; - } - -if (battery->state &0x0010 ) { -seq_printf (seq,"capacity state: critical\n" ); - }else { -seq_printf (seq,"capacity state: ok\n" ); - } - - foo = (s16 ) battery->current_now * battery->ipscale; -if (battery->mode) { - foo = foo * battery->design_voltage /1000 ; - } -if (battery->current_now <0 ) { -seq_printf (seq,"charging state: discharging\n" ); -seq_printf (seq,"present rate: %d %s\n" , - -foo, battery->mode ?"mW" :"mA" ); - }else if (battery->current_now >0 ) { -seq_printf (seq,"charging state: charging\n" ); -seq_printf (seq,"present rate: %d %s\n" , - foo, battery->mode ?"mW" :"mA" ); - }else { -seq_printf (seq,"charging state: charged\n" ); -seq_printf (seq,"present rate: 0 %s\n" , - battery->mode ?"mW" :"mA" ); - } +acpi_battery_get_state (battery); +seq_printf (seq,"capacity state: %s\n" , + (battery->state &0x0010 ) ?"critical" :"ok" ); +seq_printf (seq,"charging state: %s\n" , + (battery->current_now <0 ) ?"discharging" : + ((battery->current_now >0 ) ?"charging" :"charged" )); +seq_printf (seq,"present rate: %d mA\n" , +abs (battery->current_now) *acpi_battery_ipscale (battery));seq_printf (seq,"remaining capacity: %i%s\n" , - battery->capacity_now * cscale, - battery->mode ?"0 mWh" :" mAh" ); - + battery->capacity_now *acpi_battery_scale (battery), +acpi_battery_units (battery));seq_printf (seq,"present voltage: %i mV\n" , - battery->voltage_now * battery->vscale); + battery->voltage_now *acpi_battery_vscale (battery)); end: - -sbs_mutex_unlock (sbs); - +mutex_unlock (&sbs->lock);return result; }
@@ -849,48 +461,25 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)struct acpi_battery *battery = seq->private;struct acpi_sbs *sbs = battery->sbs;int result =0 ; -int cscale; - -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } - result =acpi_check_update_proc (sbs); -if (result) - goto end; - -if (update_time ==0 ) { - result =acpi_sbs_update_run (sbs, battery->id,DATA_TYPE_ALARM ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - } +mutex_lock (&sbs->lock);if (!battery->present) {seq_printf (seq,"present: no\n" ); goto end; } -if (battery->mode) { - cscale = battery->vscale * battery->ipscale; - }else { - cscale = battery->ipscale; - } - +acpi_battery_get_alarm (battery);seq_printf (seq,"alarm: " ); -if (battery->alarm_capacity) { +if (battery->alarm_capacity)seq_printf (seq,"%i%s\n" , - battery->alarm_capacity * cscale, - battery->mode ?"0 mWh" :" mAh" ); - }else { + battery->alarm_capacity * +acpi_battery_scale (battery), +acpi_battery_units (battery)); +else seq_printf (seq,"disabled\n" ); - } - end: - -sbs_mutex_unlock (sbs); - +mutex_unlock (&sbs->lock);return result; }
@@ -902,59 +491,28 @@ acpi_battery_write_alarm(struct file *file, const char __user * buffer,struct acpi_battery *battery = seq->private;struct acpi_sbs *sbs = battery->sbs;char alarm_string[12 ] = {'\0' }; -int result, old_alarm, new_alarm; - -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } - - result =acpi_check_update_proc (sbs); -if (result) - goto end; - +int result =0 ; +mutex_lock (&sbs->lock);if (!battery->present) { result = -ENODEV ; goto end; } -if (count >sizeof (alarm_string) -1 ) { result = -EINVAL ; goto end; } -if (copy_from_user (alarm_string, buffer, count)) { result = -EFAULT ; goto end; } - alarm_string[count] =0 ; - - old_alarm = battery->alarm_capacity; - new_alarm =simple_strtoul (alarm_string,NULL ,0 ); - - result =acpi_battery_set_alarm (battery, new_alarm); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_set_alarm() failed" )); -acpi_battery_set_alarm (battery, old_alarm); - goto end; - } - result =acpi_battery_get_alarm (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_alarm() failed" )); -acpi_battery_set_alarm (battery, old_alarm); - goto end; - } - + battery->alarm_capacity =simple_strtoul (alarm_string,NULL ,0 ); +acpi_battery_set_alarm (battery); end: -sbs_mutex_unlock (sbs); - -if (result) { +mutex_unlock (&sbs->lock); +if (result)return result; - }else { -return count; - } +return count; }static int acpi_battery_alarm_open_fs (struct inode *inode,struct file *file)
@@ -993,26 +551,15 @@ static struct proc_dir_entry *acpi_ac_dir = NULL;static int acpi_ac_read_state (struct seq_file *seq,void *offset) { -struct acpi_sbs *sbs = seq->private; -int result; -if (sbs_mutex_lock (sbs)) { -return -ENODEV ; - } +struct acpi_sbs *sbs = seq->private; -if (update_time ==0 ) { - result =acpi_sbs_update_run (sbs,-1 ,DATA_TYPE_AC_STATE ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - } +mutex_lock (&sbs->lock);seq_printf (seq,"state: %s\n" , sbs->charger_present ?"on-line" :"off-line" ); -sbs_mutex_unlock (sbs); - +mutex_unlock (&sbs->lock);return 0 ; }
@@ -1035,67 +582,54 @@ static struct file_operations acpi_ac_state_fops = {/* Smart Battery */ -static int acpi_battery_add (struct acpi_sbs *sbs,int id) +static int acpi_battery_read (struct acpi_battery *battery) { -int is_present; -int result; -char dir_name[32 ]; -struct acpi_battery *battery; +int result =0 , saved_present = battery->present; +u16 state; - battery = &sbs->battery[id]; +if (battery->sbs->manager_present) { + result =acpi_smbus_read (battery->sbs->hc,SMBUS_READ_WORD , +ACPI_SBS_MANAGER ,0x01 , (u8 *)&state); +if (!result) + battery->present = state & (1 << battery->id); + state &=0x0fff ; + state |=1 << (battery->id +12 ); +acpi_smbus_write (battery->sbs->hc,SMBUS_WRITE_WORD , +ACPI_SBS_MANAGER ,0x01 , (u8 *)&state,2 ); + }else if (battery->id ==0 ) + battery->present =1 ; +if (result || !battery->present) +return result; - battery->alive =0 ; +if (saved_present != battery->present) { + battery->update_time =0 ; + result =acpi_battery_get_info (battery); +if (result) +return result; + } + result =acpi_battery_get_state (battery); +return result; +} - battery->init_state =0 ; +static int acpi_battery_add (struct acpi_sbs *sbs,int id) +{ +int result; +struct acpi_battery *battery = &sbs->battery[id]; battery->id = id; battery->sbs = sbs; + battery->update_time =0 ; + result =acpi_battery_read (battery); +if (result) +return result; - result =acpi_battery_select (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_select() failed" )); - goto end; - } - - result =acpi_battery_get_present (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_present() failed" )); - goto end; - } - - is_present = battery->present; - -if (is_present) { - result =acpi_battery_init (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_init() failed" )); - goto end; - } - battery->init_state =1 ; - } - -sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); - - result =acpi_sbs_generic_add_fs (&battery->proc_entry, - acpi_battery_dir, - dir_name, - &acpi_battery_info_fops, - &acpi_battery_state_fops, - &acpi_battery_alarm_fops, battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_generic_add_fs() failed" )); - goto end; - } - battery->alive =1 ; - +sprintf (battery->name,ACPI_BATTERY_DIR_NAME , id); +acpi_sbs_add_fs (&battery->proc_entry, acpi_battery_dir, + battery->name, &acpi_battery_info_fops, + &acpi_battery_state_fops, &acpi_battery_alarm_fops, + battery); printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n", -ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), dir_name, - sbs->battery->present ? "present" : "absent"); - - end: +ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), + battery->name, sbs->battery->present ? "present" : "absent");return result; }
@@ -1103,354 +637,105 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) {if (sbs->battery[id].proc_entry) { -acpi_sbs_generic_remove_fs (&(sbs->battery[id].proc_entry), - acpi_battery_dir); +acpi_sbs_remove_fs (&(sbs->battery[id].proc_entry), + acpi_battery_dir); } } -static int acpi_ac_add (struct acpi_sbs *sbs) +static int acpi_charger_add (struct acpi_sbs *sbs) {int result; result =acpi_ac_get_present (sbs); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_ac_get_present() failed" )); +if (result) goto end; - } - - result =acpi_sbs_generic_add_fs (&sbs->ac_entry, - acpi_ac_dir, -ACPI_AC_DIR_NAME , -NULL , &acpi_ac_state_fops,NULL , sbs); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_generic_add_fs() failed" )); + result =acpi_sbs_add_fs (&sbs->charger_entry, acpi_ac_dir, +ACPI_AC_DIR_NAME ,NULL , + &acpi_ac_state_fops,NULL , sbs); +if (result) goto end; - } - printk(KERN_INFO PREFIX "%s [%s]: AC Adapter [%s] (%s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), ACPI_AC_DIR_NAME, sbs->charger_present ? "on-line" : "off-line"); - end: -return result; } -static void acpi_ac_remove (struct acpi_sbs *sbs) +static void acpi_charger_remove (struct acpi_sbs *sbs) { -if (sbs->ac_entry) { -acpi_sbs_generic_remove_fs (&sbs->ac_entry, acpi_ac_dir); - } -} - -static void acpi_sbs_update_time_run (unsigned long data) -{ -acpi_os_execute (OSL_GPE_HANDLER , acpi_sbs_update_time, (void *)data); +if (sbs->charger_entry) +acpi_sbs_remove_fs (&sbs->charger_entry, acpi_ac_dir); } -static int acpi_sbs_update_run (struct acpi_sbs *sbs,int id,int data_type) +void acpi_sbs_callback (void *context) { -struct acpi_battery *battery; -int result =0 , cnt; -int old_ac_present =-1 ; -int old_present =-1 ; -int new_ac_present =-1 ; -int new_present =-1 ; -int id_min =0 , id_max =MAX_SBS_BAT -1 ; -char dir_name[32 ]; -int do_battery_init =0 , do_ac_init =0 ; -int old_remaining_capacity =0 ; -int update_battery =1 ; -int up_tm = update_time; - -if (sbs_zombie (sbs)) { - goto end; - } - -if (id >=0 ) { - id_min = id_max = id; - } - -if (data_type ==DATA_TYPE_COMMON && up_tm >0 ) { - cnt = up_tm / (up_tm >UPDATE_DELAY ?UPDATE_DELAY : up_tm); -if (sbs->run_cnt % cnt !=0 ) { - update_battery =0 ; - } - } - - sbs->run_cnt++; - -if (!update_battery) { - goto end; - } - - old_ac_present = sbs->charger_present; - - result =acpi_ac_get_present (sbs); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_ac_get_present() failed" )); - } - - new_ac_present = sbs->charger_present; - - do_ac_init = (old_ac_present != new_ac_present); -if (sbs->run_cnt ==1 && data_type ==DATA_TYPE_COMMON ) { - do_ac_init =1 ; - } - -if (do_ac_init) { - result =acpi_bus_generate_proc_event4 (ACPI_AC_CLASS , -ACPI_AC_DIR_NAME , -ACPI_SBS_AC_NOTIFY_STATUS , - new_ac_present); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_bus_generate_event4() failed" )); - } -acpi_bus_generate_netlink_event (ACPI_AC_CLASS ,ACPI_AC_DIR_NAME , -ACPI_SBS_AC_NOTIFY_STATUS , - new_ac_present); - } - -if (data_type ==DATA_TYPE_COMMON ) { -if (!do_ac_init && !update_battery) { - goto end; - } - } - -if (data_type ==DATA_TYPE_AC_STATE && !do_ac_init) { - goto end; +int id; +struct acpi_sbs *sbs = context; +struct acpi_battery *bat; +u8 saved_charger_state = sbs->charger_present; +u8 saved_battery_state; +acpi_ac_get_present (sbs); +if (sbs->charger_present != saved_charger_state) { +acpi_bus_generate_proc_event4 (ACPI_AC_CLASS ,ACPI_AC_DIR_NAME , +ACPI_SBS_NOTIFY_STATUS , + sbs->charger_present); } - -for (id = id_min; id <= id_max; id++) { - battery = &sbs->battery[id]; -if (battery->alive ==0 ) { -continue ; - } - - old_remaining_capacity = battery->capacity_now; - - old_present = battery->present; - - result =acpi_battery_select (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_select() failed" )); - } - - result =acpi_battery_get_present (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_present() failed" )); - } - - new_present = battery->present; - - do_battery_init = ((old_present != new_present) - && new_present); -if (!new_present) - goto event; -if (do_ac_init || do_battery_init) { - result =acpi_battery_init (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_init() " -"failed" )); - } - } -if (sbs_zombie (sbs)) { - goto end; - } - -if ((data_type ==DATA_TYPE_COMMON - || data_type ==DATA_TYPE_INFO ) - && new_present) { - result =acpi_battery_get_info (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_info() failed" )); - } - } -if (data_type ==DATA_TYPE_INFO ) { -continue ; - } -if (sbs_zombie (sbs)) { - goto end; - } - -if ((data_type ==DATA_TYPE_COMMON - || data_type ==DATA_TYPE_STATE ) - && new_present) { - result =acpi_battery_get_state (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_state() failed" )); - } - } -if (data_type ==DATA_TYPE_STATE ) { - goto event; - } -if (sbs_zombie (sbs)) { - goto end; - } - -if ((data_type ==DATA_TYPE_COMMON - || data_type ==DATA_TYPE_ALARM ) - && new_present) { - result =acpi_battery_get_alarm (battery); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_get_alarm() " -"failed" )); - } - } -if (data_type ==DATA_TYPE_ALARM ) { -continue ; - } -if (sbs_zombie (sbs)) { - goto end; - } - - event: - -if (old_present != new_present || do_ac_init || - old_remaining_capacity != - battery->capacity_now) { -sprintf (dir_name,ACPI_BATTERY_DIR_NAME , id); - result =acpi_bus_generate_proc_event4 (ACPI_BATTERY_CLASS , - dir_name, -ACPI_SBS_BATTERY_NOTIFY_STATUS , - new_present); -acpi_bus_generate_netlink_event (ACPI_BATTERY_CLASS , dir_name, -ACPI_SBS_BATTERY_NOTIFY_STATUS , - new_present); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_bus_generate_proc_event4() " -"failed" )); - } +if (sbs->manager_present) { +for (id =0 ; id <MAX_SBS_BAT ; ++id) { +if (!(sbs->batteries_supported & (1 << id))) +continue ; + bat = &sbs->battery[id]; + saved_battery_state = bat->present; +acpi_battery_read (bat); +if (saved_battery_state == bat->present) +continue ; +acpi_bus_generate_proc_event4 (ACPI_BATTERY_CLASS , + bat->name, +ACPI_SBS_NOTIFY_STATUS , + bat->present); } } - - end: - -return result; } -static void acpi_sbs_update_time (void *data) -{ -struct acpi_sbs *sbs = data; -unsigned long delay =-1 ; -int result; -unsigned int up_tm = update_time; - -if (sbs_mutex_lock (sbs)) -return ; - - result =acpi_sbs_update_run (sbs,-1 ,DATA_TYPE_COMMON ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_update_run() failed" )); - } - -if (sbs_zombie (sbs)) { - goto end; - } - -if (!up_tm) { -if (timer_pending (&sbs->update_timer)) -del_timer (&sbs->update_timer); - }else { - delay = (up_tm >UPDATE_DELAY ?UPDATE_DELAY : up_tm); - delay = jiffies +HZ * delay; -if (timer_pending (&sbs->update_timer)) { -mod_timer (&sbs->update_timer, delay); - }else { - sbs->update_timer.data = (unsigned long )data; - sbs->update_timer.function = acpi_sbs_update_time_run; - sbs->update_timer.expires = delay; -add_timer (&sbs->update_timer); - } - } - - end: - -sbs_mutex_unlock (sbs); -} +static int acpi_sbs_remove (struct acpi_device *device,int type);static int acpi_sbs_add (struct acpi_device *device) { -struct acpi_sbs *sbs =NULL ; -int result =0 , remove_result =0 ; +struct acpi_sbs *sbs; +int result =0 ;int id; sbs =kzalloc (sizeof (struct acpi_sbs ),GFP_KERNEL );if (!sbs) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"kzalloc() failed" )); result = -ENOMEM ; goto end; } -mutex_init (&sbs->mutex); - -sbs_mutex_lock (sbs); +mutex_init (&sbs->lock); - sbs->device = device; sbs->hc =acpi_driver_data (device->parent); - + sbs->device = device;strcpy (acpi_device_name (device),ACPI_SBS_DEVICE_NAME );strcpy (acpi_device_class (device),ACPI_SBS_CLASS );acpi_driver_data (device) = sbs; - result =acpi_ac_add (sbs); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR ,"acpi_ac_add() failed" )); - goto end; - } - -acpi_sbsm_get_info (sbs); - -if (!sbs->manager_present) { - result =acpi_battery_add (sbs,0 ); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_add() failed" )); - goto end; - } - }else { -for (id =0 ; id <MAX_SBS_BAT ; id++) { -if ((sbs->batteries_supported & (1 << id))) { - result =acpi_battery_add (sbs, id); -if (result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_battery_add() failed" )); - goto end; - } - } - } - } - -init_timer (&sbs->update_timer); - result =acpi_check_update_proc (sbs); + result =acpi_charger_add (sbs);if (result) goto end; + result =acpi_manager_get_info (sbs); +if (!result) { + sbs->manager_present =1 ; +for (id =0 ; id <MAX_SBS_BAT ; ++id) +if ((sbs->batteries_supported & (1 << id))) +acpi_battery_add (sbs, id); + }else +acpi_battery_add (sbs,0 ); +acpi_smbus_register_callback (sbs->hc, acpi_sbs_callback, sbs); end: - -sbs_mutex_unlock (sbs); - -if (result) { - remove_result =acpi_sbs_remove (device,0 ); -if (remove_result) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"acpi_sbs_remove() failed" )); - } - } - +if (result) +acpi_sbs_remove (device,0 );return result; }
@@ -1459,34 +744,19 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)struct acpi_sbs *sbs;int id; -if (!device) { +if (!device)return -EINVAL ; - } - sbs =acpi_driver_data (device); -if (!sbs) { +if (!sbs)return -EINVAL ; - } - -sbs_mutex_lock (sbs); - - sbs->zombie =1 ; -del_timer_sync (&sbs->update_timer); -acpi_os_wait_events_complete (NULL ); -del_timer_sync (&sbs->update_timer); - -for (id =0 ; id <MAX_SBS_BAT ; id++) { +mutex_lock (&sbs->lock); +acpi_smbus_unregister_callback (sbs->hc); +for (id =0 ; id <MAX_SBS_BAT ; ++id)acpi_battery_remove (sbs, id); - } - -acpi_ac_remove (sbs); - -sbs_mutex_unlock (sbs); - -mutex_destroy (&sbs->mutex); - +acpi_charger_remove (sbs); +mutex_unlock (&sbs->lock); +mutex_destroy (&sbs->lock);kfree (sbs); -return 0 ; }
@@ -1505,14 +775,10 @@ static void acpi_sbs_rmdirs(void)static int acpi_sbs_resume (struct acpi_device *device) {struct acpi_sbs *sbs; -if (!device)return -EINVAL ; - sbs = device->driver_data; - - sbs->run_cnt =0 ; - +acpi_sbs_callback (sbs);return 0 ; }
@@ -1523,14 +789,6 @@ static int __init acpi_sbs_init(void)if (acpi_disabled)return -ENODEV ; -if (mode !=DEF_CAPACITY_UNIT - && mode !=MAH_CAPACITY_UNIT - && mode !=MWH_CAPACITY_UNIT ) { -ACPI_EXCEPTION ((AE_INFO ,AE_ERROR , -"invalid mode = %d" , mode)); -return -EINVAL ; - } - acpi_ac_dir =acpi_lock_ac_dir ();if (!acpi_ac_dir) { ACPI_EXCEPTION((AE_INFO, AE_ERROR,
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 30/37 ACPI: SBS: Add support for power_supply class (and sysfs)
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Add support for power_supply class and sysfs interface of it. Refer to Documentation/power_supply_class.txt for interface description.
--- drivers/acpi/Kconfig | 9 +- drivers/acpi/sbs.c | 314 +++++++++++++++++++++++++++++++++++++------------- 2 files changed, 237 insertions(+), 86 deletions(-)
drivers/acpi/Kconfig +4 -5
@@ -349,12 +349,11 @@ config ACPI_HOTPLUG_MEMORY $>modprobe acpi_memhotplug config ACPI_SBS - tristate "Smart Battery System (EXPERIMENTAL)" + tristate "Smart Battery System" depends on X86 - depends on EXPERIMENTAL + depends on POWER_SUPPLY help - This driver adds support for the Smart Battery System. - A "Smart Battery" is quite old and quite rare compared - to today's ACPI "Control Method" battery. + This driver adds support for the Smart Battery System, another + type of access to battery information, found on some laptops. endif # ACPI
drivers/acpi/sbs.c +233 -81
556 lines not on this page · raw message
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 31/37 ACPI: SBS: Add ACPI_PROCFS around procfs handling code.
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Make procfs support optional under ACPI_PROCFS
--- drivers/acpi/sbs.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
drivers/acpi/sbs.c +25 -0
@@ -29,9 +29,11 @@#include <linux/moduleparam.h> #include <linux/kernel.h> +#ifdef CONFIG_ACPI_PROCFS #include <linux/proc_fs.h> #include <linux/seq_file.h> #include <asm/uaccess.h> +#endif #include <linux/acpi.h> #include <linux/timer.h>
@@ -86,7 +88,9 @@ MODULE_DEVICE_TABLE(acpi, sbs_device_ids);struct acpi_battery {struct power_supply bat;struct acpi_sbs *sbs; +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *proc_entry; +#endif unsigned long update_time;char name[8 ];char manufacturer_name[ACPI_SBS_BLOCK_MAX ];
@@ -118,7 +122,9 @@ struct acpi_sbs {struct acpi_device *device;struct acpi_smb_hc *hc;struct mutex lock; +#ifdef CONFIG_ACPI_PROCFS struct proc_dir_entry *charger_entry; +#endif struct acpi_battery battery[MAX_SBS_BAT ]; u8 batteries_supported:4; u8 manager_present:1;
@@ -380,6 +386,8 @@ static int acpi_battery_get_state(struct acpi_battery *battery)return result; } +#ifdef CONFIG_ACPI_PROCFS +static int acpi_battery_get_alarm (struct acpi_battery *battery) { return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
@@ -416,6 +424,8 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery) return ret; } +#endif +static int acpi_ac_get_present (struct acpi_sbs *sbs) {int result;
@@ -432,6 +442,7 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)FS Interface (/proc/acpi) -------------------------------------------------------------------------- */ +#ifdef CONFIG_ACPI_PROCFS /* Generic Routines */ static int acpi_sbs_add_fs(struct proc_dir_entry **dir,
@@ -705,6 +716,8 @@ static struct file_operations acpi_ac_state_fops = { .owner = THIS_MODULE, }; +#endif +/* -------------------------------------------------------------------------- Driver Interface -------------------------------------------------------------------------- */
@@ -750,10 +763,12 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)return result;sprintf (battery->name,ACPI_BATTERY_DIR_NAME , id); +#ifdef CONFIG_ACPI_PROCFS acpi_sbs_add_fs (&battery->proc_entry, acpi_battery_dir, battery->name, &acpi_battery_info_fops, &acpi_battery_state_fops, &acpi_battery_alarm_fops, battery); +#endif battery->bat.name = battery->name; battery->bat.type =POWER_SUPPLY_TYPE_BATTERY ;if (!acpi_battery_mode (battery)) {
@@ -777,10 +792,12 @@ static void acpi_battery_remove(struct acpi_sbs *sbs, int id) {if (sbs->battery[id].bat.dev)power_supply_unregister (&sbs->battery[id].bat); +#ifdef CONFIG_ACPI_PROCFS if (sbs->battery[id].proc_entry) {acpi_sbs_remove_fs (&(sbs->battery[id].proc_entry), acpi_battery_dir); } +#endif }static int acpi_charger_add (struct acpi_sbs *sbs)
@@ -790,11 +807,13 @@ static int acpi_charger_add(struct acpi_sbs *sbs) result =acpi_ac_get_present (sbs);if (result) goto end; +#ifdef CONFIG_ACPI_PROCFS result =acpi_sbs_add_fs (&sbs->charger_entry, acpi_ac_dir,ACPI_AC_DIR_NAME ,NULL , &acpi_ac_state_fops,NULL , sbs);if (result) goto end; +#endif sbs->charger.name ="sbs-charger" ; sbs->charger.type =POWER_SUPPLY_TYPE_MAINS ; sbs->charger.properties = sbs_ac_props;
@@ -812,8 +831,10 @@ static void acpi_charger_remove(struct acpi_sbs *sbs) {if (sbs->charger.dev)power_supply_unregister (&sbs->charger); +#ifdef CONFIG_ACPI_PROCFS if (sbs->charger_entry)acpi_sbs_remove_fs (&sbs->charger_entry, acpi_ac_dir); +#endif }void acpi_sbs_callback (void *context)
@@ -916,6 +937,7 @@ static int acpi_sbs_remove(struct acpi_device *device, int type)static void acpi_sbs_rmdirs (void ) { +#ifdef CONFIG_ACPI_PROCFS if (acpi_ac_dir) {acpi_unlock_ac_dir (acpi_ac_dir); acpi_ac_dir =NULL ;
@@ -924,6 +946,7 @@ static void acpi_sbs_rmdirs(void)acpi_unlock_battery_dir (acpi_battery_dir); acpi_battery_dir = NULL; } +#endif }static int acpi_sbs_resume (struct acpi_device *device)
@@ -953,6 +976,7 @@ static int __init acpi_sbs_init(void)if (acpi_disabled)return -ENODEV ; +#ifdef CONFIG_ACPI_PROCFS acpi_ac_dir =acpi_lock_ac_dir ();if (!acpi_ac_dir)return -ENODEV ;
@@ -961,6 +985,7 @@ static int __init acpi_sbs_init(void)acpi_sbs_rmdirs (); return -ENODEV; } +#endif result =acpi_bus_register_driver (&acpi_sbs_driver);if (result <0 ) {acpi_sbs_rmdirs ();
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 32/37 ACPI: SBS: Add sysfs alarm
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
--- drivers/acpi/sbs.c | 36 ++++++++++++++++++++++++++++++++---- 1 files changed, 32 insertions(+), 4 deletions(-)
drivers/acpi/sbs.c +32 -4
@@ -386,8 +386,6 @@ static int acpi_battery_get_state(struct acpi_battery *battery)return result; } -#ifdef CONFIG_ACPI_PROCFS -static int acpi_battery_get_alarm (struct acpi_battery *battery) { return acpi_smbus_read(battery->sbs->hc, SMBUS_READ_WORD,
@@ -424,8 +422,6 @@ static int acpi_battery_set_alarm(struct acpi_battery *battery)return ret; } -#endif -static int acpi_ac_get_present (struct acpi_sbs *sbs) {int result;
@@ -438,6 +434,36 @@ static int acpi_ac_get_present(struct acpi_sbs *sbs)return result; } +static ssize_t acpi_battery_alarm_show (struct device *dev, +struct device_attribute *attr, +char *buf) +{ +struct acpi_battery *battery =to_acpi_battery (dev_get_drvdata (dev)); +acpi_battery_get_alarm (battery); +return sprintf (buf,"%d\n" , battery->alarm_capacity * +acpi_battery_scale (battery) *1000 ); +} + +static ssize_t acpi_battery_alarm_store (struct device *dev, +struct device_attribute *attr, +const char *buf,size_t count) +{ +unsigned long x; +struct acpi_battery *battery =to_acpi_battery (dev_get_drvdata (dev)); +if (sscanf (buf,"%ld\n" , &x) ==1 ) + battery->alarm_capacity = x / + (1000 *acpi_battery_scale (battery)); +if (battery->present) +acpi_battery_set_alarm (battery); +return count; +} + +static struct device_attribute alarm_attr = { + .attr = {.name ="alarm" , .mode =0644 , .owner =THIS_MODULE }, + .show = acpi_battery_alarm_show, + .store = acpi_battery_alarm_store, +}; +/* -------------------------------------------------------------------------- FS Interface (/proc/acpi) -------------------------------------------------------------------------- */
@@ -782,6 +808,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id) } battery->bat.get_property = acpi_sbs_battery_get_property; result =power_supply_register (&sbs->device->dev, &battery->bat); +device_create_file (battery->bat.dev, &alarm_attr); printk(KERN_INFO PREFIX "%s [%s]: Battery Slot [%s] (battery %s)\n",ACPI_SBS_DEVICE_NAME ,acpi_device_bid (sbs->device), battery->name, sbs->battery->present ? "present" : "absent");
@@ -791,6 +818,7 @@ static int acpi_battery_add(struct acpi_sbs *sbs, int id)static void acpi_battery_remove (struct acpi_sbs *sbs,int id) {if (sbs->battery[id].bat.dev) +device_remove_file (sbs->battery[id].bat.dev, &alarm_attr);power_supply_unregister (&sbs->battery[id].bat);#ifdef CONFIG_ACPI_PROCFS if (sbs->battery[id].proc_entry) {
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 33/37 ACPI: AC: Add sysfs interface
In reply to Len BrownFrom: Alexey Starikovskiy <[email protected]>
Refer to Documentation/power_supply_class.txt for interface description.
--- drivers/acpi/Kconfig | 2 +- drivers/acpi/ac.c | 33 +++++++++++++++++++++++++++++++-- 2 files changed, 32 insertions(+), 3 deletions(-)
drivers/acpi/Kconfig +1 -1
@@ -88,7 +88,7 @@ config ACPI_PROC_EVENT config ACPI_AC tristate "AC Adapter" - depends on X86 + depends on X86 && POWER_SUPPLY default y help This driver adds support for the AC Adapter object, which indicates
drivers/acpi/ac.c +31 -2
@@ -29,6 +29,7 @@#include <linux/types.h> #include <linux/proc_fs.h> #include <linux/seq_file.h> +#include <linux/power_supply.h> #include <acpi/acpi_bus.h> #include <acpi/acpi_drivers.h>
@@ -72,16 +73,37 @@ static struct acpi_driver acpi_ac_driver = { };struct acpi_ac { +struct power_supply charger;struct acpi_device * device;unsigned long state; }; +#define to_acpi_ac (x) container_of(x, struct acpi_ac, charger); +static const struct file_operations acpi_ac_fops = { .open = acpi_ac_open_fs, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; +static int get_ac_property (struct power_supply *psy, +enum power_supply_property psp, +union power_supply_propval *val) +{ +struct acpi_ac *ac =to_acpi_ac (psy); +switch (psp) { +case POWER_SUPPLY_PROP_ONLINE : + val->intval = ac->state; +break ; +default : +return -EINVAL ; + } +return 0 ; +} + +static enum power_supply_property ac_props[] = { +POWER_SUPPLY_PROP_ONLINE , +};/* -------------------------------------------------------------------------- AC Adapter Management
@@ -208,6 +230,7 @@ static void acpi_ac_notify(acpi_handle handle, u32 event, void *data)acpi_bus_generate_netlink_event (device->pnp.device_class, device->dev.bus_id, event, (u32 ) ac->state); +kobject_uevent (&ac->charger.dev->kobj,KOBJ_CHANGE );break ;default : ACPI_DEBUG_PRINT((ACPI_DB_INFO,
@@ -244,7 +267,12 @@ static int acpi_ac_add(struct acpi_device *device) result =acpi_ac_add_fs (device);if (result) goto end; - + ac->charger.name =acpi_device_bid (device); + ac->charger.type =POWER_SUPPLY_TYPE_MAINS ; + ac->charger.properties = ac_props; + ac->charger.num_properties =ARRAY_SIZE (ac_props); + ac->charger.get_property = get_ac_property; +power_supply_register (&ac->device->dev, &ac->charger); status =acpi_install_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_ac_notify, ac);
@@ -279,7 +307,8 @@ static int acpi_ac_remove(struct acpi_device *device, int type) status =acpi_remove_notify_handler (device->handle,ACPI_ALL_NOTIFY , acpi_ac_notify); - +if (ac->charger.dev) +power_supply_unregister (&ac->charger);acpi_ac_remove_fs (device);kfree (ac);
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 34/37 ACPI: thinkpad-acpi: skip blanks before the data when parsing sysfs
In reply to Len BrownFrom: Henrique de Moraes Holschuh <[email protected]>
Skip blanks not just at the tail of sysfs writes, but also at the head.
--- drivers/misc/thinkpad_acpi.c | 2 ++ 1 files changed, 2 insertions(+), 0 deletions(-)
drivers/misc/thinkpad_acpi.c +2 -0
@@ -709,6 +709,8 @@ static int parse_strtoul(const char *buf, {char *endp; +while (*buf &&isspace (*buf)) + buf++; *value =simple_strtoul (buf, &endp,0 );while (*endp &&isspace (*endp)) endp++;
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 35/37 ACPI: suppress uninitialized var warning
In reply to Len BrownFrom: Andrew Morton <[email protected]>
drivers/acpi/tables/tbutils.c: In function `acpi_tb_parse_root_table':drivers/acpi/tables/tbutils.c:403: warning: `rsdt_address' may be used uninitialized in this function
--- drivers/acpi/tables/tbutils.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-)
drivers/acpi/tables/tbutils.c +1 -1
@@ -400,7 +400,7 @@ acpi_tb_parse_root_table(acpi_physical_address rsdp_address, u8 flags)u32 table_count;struct acpi_table_header *table;acpi_physical_address address; -acpi_physical_address rsdt_address; +acpi_physical_address uninitialized_var (rsdt_address );u32 length;u8 *table_entry;acpi_status status;
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 36/37 Hibernation: Make sure that ACPI is enabled in acpi_hibernation_finish
In reply to Len BrownFrom: Rafael J. Wysocki <[email protected]>
If the BIOS does not enable ACPI and the "acpi=off" command line parameter is passed to the boot kernel, ACPI may be disabled when the (restored) image kernel attempts to execute acpi_hibernation_finish(). To prevent this from happening we can call acpi_enable() from acpi_hibernation_finish() (if ACPI is already enabled, this will have no effect).
--- drivers/acpi/sleep/main.c | 5 +++++ 1 files changed, 5 insertions(+), 0 deletions(-)
drivers/acpi/sleep/main.c +5 -0
@@ -256,6 +256,11 @@ static int acpi_hibernation_enter(void)static void acpi_hibernation_finish (void ) { +/* +* If ACPI is not enabled by the BIOS and the boot kernel, we need to +* enable it here. +*/ +acpi_enable ();acpi_leave_sleep_state (ACPI_STATE_S4 );acpi_disable_wakeup_device (ACPI_STATE_S4 );
Signature · 1 line
1.5.3.4.206.g58ba4
Len Brown
reviewerPATCH 37/37 ACPI: clean up acpi_enter_sleep_state_prep
In reply to Len BrownFrom: Rafael J. Wysocki <[email protected]>
Remove some redundant code from acpi_enter_sleep_state_prep() and clean up a comment in there.
--- drivers/acpi/hardware/hwsleep.c | 10 +++------- 1 files changed, 3 insertions(+), 7 deletions(-)
drivers/acpi/hardware/hwsleep.c +3 -7
@@ -234,15 +234,11 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state) "While executing method _SST")); } -/* -* 1) Disable/Clear all GPEs -*/ +/* Disable/Clear all GPEs */ + status =acpi_hw_disable_all_gpes (); -if (ACPI_FAILURE (status)) { -return_ACPI_STATUS (status); - } -return_ACPI_STATUS (AE_OK ); +return_ACPI_STATUS (status); }ACPI_EXPORT_SYMBOL (acpi_enter_sleep_state_prep)
Signature · 1 line
1.5.3.4.206.g58ba4